從經典的 for 循環到forEach()
方法,用於迭代數據集合的各類技術和方法比比皆是。可是如今比較流行的方法是.map()
方法。前端
.map()
經過指定函數調用一個數組中每一項元素,來建立一個新數組。.map()
是一種 non-mutating(非變異) 方法,它建立一個新數組,而不是隻對調用數組進行更改的 mutating(變異) 方法。這可能很難記住。react
在這篇文章中,咱們將探討一下 JavaScript 中.map()
的 4 個值得注意的用法。讓咱們開始!數組
在數組中的每一項元素上調用一個函數
將字符串轉換爲數組
在 JavaScript 庫中用於渲染列表
從新格式化數組對象
小技巧使用案例dom
如前所述,.map()
接受回調函數做爲其參數之一,該函數的一個重要參數是由該函數處理的項的當前值。這是一個必需的參數。有了這個參數,咱們能夠修改數組中的每一個單獨項,並在其上建立一個新元素。這裏有一個例子:函數
const sweetArray = [2, 3, 4, 5, 35] const sweeterArray = sweetArray.map(sweetItem => { return sweetItem * 2 }) console.log(sweetArray) // [2, 3, 4, 5, 35] console.log(sweeterArray) // [4, 6, 8, 10, 70]
咱們能夠看到,原數組sweetArray
並無被修改,因此.map()
是一種non-mutating(非變異)
方法。這裏值得一提的是 forEach() 方法,它是遍歷數組,對原來的數據操做,會改變原數組。ui
這甚至能夠進一步簡化,使其更清潔:prototype
// 建立一個要使用的函數 const makeSweeter = sweetItem => sweetItem * 2; // 咱們有一個數組 const sweetArray = [2, 3, 4, 5, 35]; // 調用咱們製做的函數。更具可讀性 const sweeterArray = sweetArray.map(makeSweeter); console.log(sweeterArray); // [4, 6, 8, 10, 70]
擁有像sweetArray.map(makeSweeter)
這樣的代碼可讓你在跳轉到這段代碼時更具可讀性。code
將字符串轉換爲數組
已知的.map()
屬於 Array 原型。 咱們如何使用它將字符串轉換爲數組。 不用擔憂,咱們不須要再開發一個方法來處理字符串,而是使用特殊的.call()
方法。對象
JavaScript 中的全部內容都是對象,方法只是附加到這些對象的函數。.call()
容許咱們利用另外一個對象的上下文。 所以,咱們將數組中的.map()
上下文複製到字符串。索引
.call()
能夠傳遞參數,要使用的上下文和「參數原始函數的參數」。 聽起來有點拗口? 這是一個例子:
const name = "Chuloo" const map = Array.prototype.map const newName = map.call(name, eachLetter => { return `${eachLetter}a` }) console.log(newName) // ["Ca", "ha", "ua", "la", "oa", "oa"]
這裏,咱們只是在String上使用.map()
的上下文,並傳遞了.map()
所指望的函數參數。 你能夠看看控制檯裏打印出來的內容。
這相似於 String 的.split()
方法,不過.split()
方法只能在返回數組以前修改每一個單獨的字符串字符。
像React 這樣的 JavaScript 庫利用.map()
來渲染列表中的項目。這須要 JSX 語法,可是.map()
方法包含在相似於 mustache 的 JSX 語法中。這是 React 組件的一個很好的例子。
import React from "react"; import ReactDOM from "react-dom"; const names = ["john", "sean", "mike", "jean", "chris"]; const NamesList = () => (
{names.map(name =>
{name}
)}
); const rootElement = document.getElementById("root"); ReactDOM.render(
, rootElement);
若是你不熟悉 React ,那麼我告訴這是 React 中的一個簡單的無狀態組件,它使用列表渲染div。 使用.map()
渲染單個列表項以迭代最初建立的names
數組。 此組件使用 ReactDOM 渲染 ID爲 root 的 DOM 元素 。
如何處理數組中的對象?.map()
可用於迭代數組中的對象,並以與傳統數組相似的方式, 修改每一個單獨對象的內容 並返回一個新數組。 這個修改是基於回調函數中返回的內容來完成的。這裏有一個例子:
const myUsers = [ { name: 'chuloo', likes: 'grilled chicken' }, { name: 'chris', likes: 'cold beer' }, { name: 'sam', likes: 'fish biscuits' } ] const usersByFood = myUsers.map(item => { const container = {}; container[item.name] = item.likes; container.age = item.name.length * 10; return container; }) console.log(usersByFood); // [{chuloo: "grilled chicken", age: 60}, {chris: "cold beer", age: 50}, {sam: "fish biscuits", age: 30}]
咱們所作的就是使用括號和點符號簡單地修改數組中的每一個對象。這個用例能夠用於在前端應用程序上保存或解析以前處理或壓縮接收到的數據。
一般狀況下,.map()
方法中的 callback 函數只須要接受一個參數,就是正在被遍歷的數組元素自己。但這並不意味着 map 只給 callback 傳了一個參數。這個思惟慣性可能會讓咱們犯一個很容易犯的錯誤。 生成新數組元素的 callback 函數,有 三個參數:
currentValue – callback 的第一個參數,數組中正在處理的當前元素,最經常使用的參數。
index – callback 的第二個參數,數組中正在處理的當前元素的索引。
array – callback 的第三個參數,map 方法被調用的數組。
來看一下例子:
// 下面的語句返回什麼呢: ["1", "2", "3"].map(parseInt); // 你可能覺的會是[1, 2, 3] // 但實際的結果是 [1, NaN, NaN] // 一般使用parseInt時,只須要傳遞一個參數. // 但實際上,parseInt能夠有兩個參數.第二個參數是進制數. // 能夠經過語句"alert(parseInt.length)===2"來驗證. // map方法在調用callback函數時,會給它傳遞三個參數:當前正在遍歷的元素, // 元素索引, 原數組自己. // 第三個參數parseInt會忽視, 但第二個參數不會,也就是說, // parseInt把傳過來的索引值當成進制數來使用.從而返回了NaN. function returnInt(element) { return parseInt(element, 10); } ['1', '2', '3'].map(returnInt); // [1, 2, 3] // 意料之中的結果 // 也可使用簡單的箭頭函數,結果同上 ['1', '2', '3'].map( str => parseInt(str) ); // 一個更簡單的方式: ['1', '2', '3'].map(Number); // [1, 2, 3] // 與`parseInt` 不一樣,下面的結果會返回浮點數或指數: ['1.1', '2.2e2', '3e300'].map(Number); // [1.1, 220, 3e+300]
還有一個很是實用的小技巧,像.map()
,.reduce()
,.filter()
這些方法支持鏈式調用。例如:
var myArr = [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 ]; var result = myArr .map(function(element) { // 數值大於5的數值視爲5 if (element > 5) return 5; return element; }) .reduce(function(prev, element) { // 與以前的數值加總,回傳後代入下一輪的處理 return prev + element; }, 0); // 40 console.log(result);
在這篇文章中,咱們研究了 JavaScript 中 .map() 方法的主要用途。 須要注意的是,與其餘方法結合使用時, .map() 的函數能夠獲得強大的擴展和利用。 嘗試找出更多用例。 在評論區留下您的意見,問題和反饋,咱們將不勝感激!