# Map() 、 forEach() 差異
本文作者學習筆記網站:https://dev.rraiy.cc/
---
[Can you describe the main difference between a .forEach loop and a .map() loop and why you would pick one versus the other?](https://github.com/yangshun/front-end-interview-handbook/blob/master/contents/en/javascript-questions.md#can-you-describe-the-main-difference-between-a-foreach-loop-and-a-map-loop-and-why-you-would-pick-one-versus-the-other)
### 兩者差異
#### The big alert !!!! map會回傳新的陣列,forEach不會
||說明|參數|回傳值|其他|
|-|-|-|-|-|
|map|抓出陣列中每個項目,對其執行給定的函式或邏輯,將每個處理結果包裝成新陣列回傳|(callback func, thisArg)|新的array|會略過空項目、不能中斷(可用for..of)、即使回傳值不改變原陣列,仍可以把回傳值=原陣列來達成效果
|forEach|抓出陣列中每個項目,對其執行給定的函式或邏輯,可能會修改原陣列,不會回傳新陣列|(callback func, thisArg)|undefined|會略過空項目、不能中斷|
#### 口語解釋 (by Vue作者尤雨溪)
+ forEach 就是你一個個跟他們指定要做什麼,他們就做什麼。
+ map 你拿著一個盒子,要這些人一個個把錢包丟進盒子裡,你的盒子成了新Array,裡面有著大家的錢包且跟人的順序一一對應。
+ 順便補充:reduce是你把錢包一個一個數,每檢查一個,就和前一個值加總,到最後就知道大家共有多少錢。
#### 參數
map跟forEach可以帶的參數都一樣
(callback func, thisArg)
callback func裡可以再帶三個參數(item, index, array)
thisArg可以指定該作用域裡的this指向(箭頭函式不可)
#### 看實際code
```javascript=
// * 觀察回傳值
let originalData = [1, 2, 3, 4, 5];
let test_foreach = originalData.forEach((item) => {
return item;
});
// console.log(test_foreach)
let test_map = originalData.map((item) => {
return item;
});
// console.log(test_map)
//---------------------------------------------------
// * 是否操作到原物件 先想一下以下答案
// (1)
let data2 = [5, 5, 6, 6]; // 值value
data2.forEach((item) => (item = item * 2));
// console.log(data2)
// (2)
const data3 = [ // 引用reference
{
group: "5566",
CD: 56
},
{
group: "SHE",
CD: 480
},
{
group: "Imagine Dragons",
CD: 1500
}
];
data3.forEach((item) => (item.CD = item.CD * 2));
console.log(data3)
//---------------------------------------------------
// * map如何達成更新原陣列?
const data4 = [5, 5, 6, 6];
data4 = data4.map((item) => item * 2);
// console.log(data4)
//---------------------------------------------------
// * 搭配鏈式
// forEach
let data5 = ['喜劇', '動作', '恐怖'];
let jsxData = data5.forEach((item, key) => {
return `<li key=${key}>${item}</li>`;
})
// .join('');
// console.log(jsxData)
// map
let data6 = ['喜劇', '動作', '恐怖'];
let jsxData2 = data6.map((item, key) => {
return `<li key=${key}>${item}</li>`;
}).join('')
// console.log(jsxData2)
// console.log({jsxData2})
//---------------------------------------------------
// thisArg的功用 ..... 但現在我也不知道能幹嘛 抱歉QQ
let obj = {name: "Jolin"};
[1].map(function(){
// console.log(this) //指向obj
},obj)
let obj2 = {name: "Jolin"};
[1].map(()=>console.log(this) // undefined
, obj2)
```
### 觀念總結:
1. 能用forEach處理,大部分也可以用map處理,反之亦然
2. 需要新陣列就用map,其他就是forEach
3. map很好搭配其他method繼續處理下去(做到鏈式),要記住forEach沒有回傳值所以做不到鏈式
4. forEach不會改變值類型,會改變引用類型(值與引用差異可以回想彭彭之前上過的mutable vs. immutable) [這篇也不錯清楚](https://www.cnblogs.com/leiting/p/8081413.html) 可以參考
5. map千萬別忘了return,否則就是空陣列
---
本文作者學習筆記網站:https://dev.rraiy.cc/
---
##### 參考文章
[JavaScript — Map vs. ForEach](https://codeburst.io/javascript-map-vs-foreach-f38111822c0f)
[用土豆理解陣列遍歷,不只map forEach](https://juejin.cn/post/6844903870154588168)