# 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)