【譯】map & forEach 的區別

原文: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 快,爲了驗證,我找了如下對比:

img

img

代碼看起來差很少,可是結果卻截然相反。一些 test cases 顯示 forEach 快,一些顯示 map 快。老實說,我也不肯定,可是我覺的在現代 web 開發中沒必要糾結這點速度,代碼的可讀性更重要。

但有一點很肯定,他們都比 for 循環慢。

結論

map & forEach 都是遍歷可迭代對象的利器,能夠簡化代碼,增長代碼的可讀性。咱們只需區分使用它們的場景就行。

相關文章
相關標籤/搜索