forEach()和map()都是處理數組的高階函數有相同的三個值:(currentValue,index,arr);
currentValue:必選,當前元素的值,index:可選,當前元素的下標,arr:可選,當前遍歷的數組對象
語法:
let array = [{title:"雪碧",price:2.5},{title:"可樂",price:2.5}]
let list = []
array.forEach((item,index,arr)=>{
list[index] = item; 或者 list[index].title = item.title; list[index].price= item.price
})
list = array.map((item,index,arr)=>{
let arrs = {
title:item.title,
item:item.price
}
return arrs;
或者
return {
title:item.title,
item:item.price
}
})
那么,forEach和map都有相同三個值,他們有什么區別呢?
相同處:forEach 和 map都相當於封裝好的單層for循環,三個值都相同。
不同處:
一:forEach()方法沒有返回值,而map()方法有返回值;
二:forEach遍歷通常都是直接引入當前遍歷數組的內存地址,生成的數組的值發生變化,當前遍歷的數組對應的值也會發生變化;
三:map遍歷的后的數組通常都是生成一個新的數組,新的數組的值發生變化,當前遍歷的數組值不會變化;
總結一下:這里我為什么都說遍歷后通常是引入當前遍歷數組的內存地址和生成一個新的數組,因為按forEach和map創作思想,forEach遍歷基本引入遍歷數組內存地址、map遍歷而是生成一個新的數組,但是有些人寫的時候不按map和forEach的常規語法來,導致使用map遍歷數組時,返回的值是直接把當前遍歷數組的每個元素的內存地址給了另外一個數組,本質還是引用遍歷數組中每個元素的內存地址,這樣生成的數組已經不能稱作為一個新的數組同樣也把map最大的一個特性給舍棄了,同理如果map和forEach本質沒區別的話,開發人員沒必要把他們封裝成兩個函數,封裝成一個就好了。
如果對於上面說法有不懂的,可以看帶着疑問看下面案例
案例一:
代碼:
let arr = [ { title:'雪碧', price: 2.5, }, { title:'可樂', price: 2.5, } ] let a = arr.forEach((item,index) =>{ return item }) let b = arr.map((item,index) =>{ return item }) console.log(arr) //打印arr數組 console.log(a) //undefined console.log(b) //打印arr數組
控制台:
從案例一可以看出來,map方法是有返回值的,而forEach方法沒有返回值,但是如果用map方法想讓b獲取arr的數組的值,不建議案例一中的寫法,因為上面我們已經說到了map方法主要是生成一個新的數組,而不是直接引入arr數組內存地址,如果有不明白的我們來看下面的案例你就會懂了。
案例二:
代碼:
let arr = [{title:'雪碧',price: 2.5},{title:'可樂',price: 2.5}] let list = [{title:'雪碧',price: 2.5},{title:'可樂',price: 2.5}] let a = []; let b = []; arr.forEach((item,index) =>{ a[index] = item; }) b = list.map((item,index) =>{ return item }) console.log(a) console.log(b)
控制台:
到這里我們可以看到,a和b都已經成功的接收了arr和list的數組的數據,上面我一直強調map一定不要直接return item,這里這么寫主要是為了讓你們區分生成新數組和內存地址的區別
代碼:
a[0].price = 3; b[0].price = 3; console.log(a); console.log(b); console.log(arr) console.log(list)
控制台:
從這里我們看到只更改了a和b中price值,但是arr和list數組price的值也發生了變化,arr發生變化屬於正常現象,因為在上述中已經說過forEach方法遍歷通常都是引入遍歷數組的內存地址,不管是arr發生改變還是a發生改變,其實都是直接改變同一個內存地址,所以他們的值會一直同步,但是map方法不是說生成的是一個新的數組,為什么b的值發生改變,list值同樣發生改變呢,這里就是上述說的內存地址引入問題。
案例三:
代碼:
b = list.map((item,index) =>{ return{ title:item.title, price:item.price } }) b[0].price = 3; console.log(b); console.log(list)
控制台:
在這里我們改變一下寫法,就會發現現在在改變b值的,list的就不會發生變化了,案例二中改變b的值,list的值發現變化是因為雖說map遍歷后生成的是一個新的數組,但是在遍歷的過程還是引入舊數組的內容地址,而在案例三中我們通過map遍歷的時候自己定義一下想要參數名,只復制一下舊數組的值,遍歷完后會生成新的內存空間去存儲b的值,所以我們在改變b的值時候也只是改變了b內存中的值,而沒有改變list內存的值,同樣的在改變list的值,b的值也不會發現改變,所以說map方法遍歷后會生成一個新的數組。