原文:What Is the Difference Between map() and forEach() in JavaScript?javascript
map & forEach 都是從 es5 纔開始出現,本文會討論它們之間主要的區別以及如何使用它們。java
map & forEach 都是用來更方便地遍歷數組的。web
map 接收兩個參數:callback 函數,它會在 map 執行以後被觸發。上下文變量,即執行 callback 函數時 this 指向的對象。map 會返回一個新數組。數組
map(callback[, thisArg])函數
[1, 2, 3].map(function(value, index, originalArray) {
console.log(`${index}: ${value} / ${originalArray} /`);
console.log(this);
return value + 1;
}, { test: 1 });
// 0: 1 / 1,2,3 / {test: 1}
// 1: 2 / 1,2,3 / {test: 1}
// 2: 3 / 1,2,3 / {test: 1}
// 返回值:[2, 3, 4]
複製代碼
注意:map 的返回不等於原數組:ui
const arr = [1];
const new_arr = arr.map(d => d);
arr === new_arr; // false
複製代碼
forEach 接收的參數和 map 相同,可是它沒有返回值,即它返回的是 undefined。this
forEach(callback[, thisArg])es5
[1, 2, 3].forEach(function(value, index, originalArray) {
console.log(`${index}: ${value} / ${originalArray} /`);
console.log(this);
}, { test: 1 });
// 0: 1 / 1,2,3 / {test: 1}
// 1: 2 / 1,2,3 / {test: 1}
// 2: 3 / 1,2,3 / {test: 1}
// 返回值:undefined
複製代碼
由於 map & forEach 的主要區別是有無返回,因此,當你想基於一個原數組返回一個新數組,能夠選擇 map,當你只是想遍歷數據不須要考慮返回時能夠選擇 forEach。spa
mapcode
const people = [
{ name: 'Josh', whatCanDo: 'painting' },
{ name: 'Lay', whatCanDo: 'security' },
{ name: 'Ralph', whatCanDo: 'cleaning' }
];
function makeWorkers(people) {
return people.map((person) => {
const { name, whatCanDo } = person;
return <li key={name}>My name is {name}, I can do {whatCanDo}</li>
});
}
<ul>makeWorkers(people)</ul>
複製代碼
注意:map 遍歷數組時,每次都會返回一個值,若是沒有顯示返回,就返回 undefined,如 e.g.1。
const metrics = [
{ id: 'sales', selected: true, title: 'Sales'},
{ id: 'units', selected: true, title: 'Units'},
{ id: 'buyers', selected: false, title: 'Buyers'}
]
e.g.1
const ids = metrics.map(item => {
if(item.selected) {
return item.id
}
})
// ["sales", "units", undefined]
複製代碼
在實際開發中我碰到這樣一個邏輯:返回 metrics 中 selected:true 的元素的 id 組成的數組,由於想用一個函數搞定,而後就寫了 e.g.2 這段代碼,然鵝。。。能夠選擇用 e.g.3 / e.g.4 / e.g.5。
e.g.2
const ids = metrics.map(item => item.selected && item.id)
// ["sales", "units", false]
e.g.3
const ids = metrics.filter(item => item.selected).map(item => item.id)
e.g.4
const ids = []
metrics.forEach(item => {
item.selected && ids.push(item.id)
}
e.g.5
const ids = metrics.reduce((newArr, item) => {
item.selected && newArr.push(item.id)
return newArr;
}, []);
複製代碼
一些文章說 map 比 forEach 快,爲了驗證,我找了如下對比:
代碼看起來差很少,可是結果卻截然相反。一些 test cases 顯示 forEach 快,一些顯示 map 快。老實說,我也不肯定,可是我覺的在現代 web 開發中沒必要糾結這點速度,代碼的可讀性更重要。
但有一點很肯定,他們都比 for 循環慢。
map & forEach 都是遍歷可迭代對象的利器,能夠簡化代碼,增長代碼的可讀性。咱們只需區分使用它們的場景就行。