JS 中 map 和 forEach 的區別,很多地方都搞錯了!

寫 JS 代碼用到的時候,以前我一般都用 for 或 for in ,少數情況下用 while ,後來 JS 的數組出了幾個可用於循環的函數,但因爲考慮兼容性問題,一開始我基本不用。 隨着這些標準逐漸被支持,基本上不用考慮兼容性問題了,於是我就漸漸地試着用起這些函數來了。

用得最多的無疑是 map 和 forEach ,很多時候也只是需要循環一下,用哪個都差不多,於是看心情用 map 或 forEach ,但從函數名的長度來看,我當然會更傾向於使用 map 函數,但又因爲寫多了 PHP,習慣了 PHP 裏的 foreach ,所以對 forEach 也有一定的好感。

不查資料我真的不知道這兩個函數之間有什麼區別,於是出於好奇,我還是去搜索了一下。

找到的結果基本都是這樣的:

有些文章還給我舉例來了:

說得頭頭是道,但這兩個例子明顯舉得有問題,你發現了嗎? 在用 forEach 的時候,是用:

 value.id = index+1

這明顯修改了 value 的值

而用 map 的時候 卻是:

return { ...value ,id:index+1}

這裏並沒有去修改原數組的元素。

如果用 map 的時候,也是:

 value.id = index+1

你看一下會不會修改到原數組?!

用 forEach:

var arr=[
    {
        id:1,
        name:"hi"
    },
    {
        id:2,
        name:"he"
    },
    {
        id:3,
        name:"hello"
    }
];
arr.forEach((v,i)=>{
    v.name="_"+v.name;
    v.age=i*10;
})
console.log(arr);
/*
[
  { id: 1, name: '_hi', age: 0 },
  { id: 2, name: '_he', age: 10 },
  { id: 3, name: '_hello', age: 20 }
]
*/

用 map:

var arr=[
    {
        id:1,
        name:"hi"
    },
    {
        id:2,
        name:"he"
    },
    {
        id:3,
        name:"hello"
    }
];
arr.map((v,i)=>{
    v.name="_"+v.name;
    v.age=i*10;
})
console.log(arr);
/*
[
  { id: 1, name: '_hi', age: 0 },
  { id: 2, name: '_he', age: 10 },
  { id: 3, name: '_hello', age: 20 }
]
*/

我們可以看到,使用 map 的時候,只要你在循環內修改了數組的元素,一樣會影響到原數組,並不是很多地方說的 map 不會修改原數組。

當然,也有循環體內修改了元素,也不會對數組有影響的,比如:

var num=[1,2,3,4,5];
num.forEach((v,i)=>{
    v=v+i;
})
console.log(num);//[1,2,3,4,5]

var num2=[1,2,3,4,5];
num2.map((v,i)=>{
    v=v+i;
})
console.log(num2);//[1,2,3,4,5]

我們可以看到,儘管我在循環體內修改了元素:v=v+i;但原數據並沒有被修改。

爲什麼呢? 其實有點 JS 常識的都應該知道,當數組的元素是對象時,就像我們把一個對象賦值給另一個變量,修改另一個變量是會影響到原變量的;而當一個變量是數字或字符串時則不會有影響。 所以,map 和 forEach 的區別根本和是否會修改到原數組沒有關係。

它們最主要的區別是 map 有返回值,而 forEach 沒有返回值。

我們再來看一段代碼:

var num=[1,2,3,4,5];
var a=num.forEach((v,i)=>{
    return v+i; //其實這裏用不用 return ,效果都一樣
})
console.log(a);//undefined

var num2=[1,2,3,4,5];
var b=num2.map((v,i)=>{
    return v=v+i;
})
console.log(b);//[ 1, 3, 5, 7, 9 ]

所以,當我們只是需要一個循環,而不是需要通過一個數組去創建一個新的數組的時候,用 forEach 和 map 都可以,如果需要通過一個數組去創建一個新數組的話,用 map 。但需要注意的是,如果不想修改到原數組,當數組的元素是對象的時候,循環體內不要去修改它。 如果我們想通過修改舊數組得到一個新數組,但用 map 和 forEach 都可以。

但無論是 map 還是 forEach 在循環內都不能使用 break 或 return 去終於循環,如果你希望查找到某個元素後都退出循環的,那還是需要用回循環的語法,而不是數組迭代函數。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章