JavaScript中forEach和map詳細講解
基本用法
forEach和map都是JavaScript中常見的用于遍歷數(shù)組的方法,它們都可以用于對數(shù)組中的每個元素執(zhí)行某種操作,但它們的使用方式和返回結(jié)果略有不同。
forEach
forEach是一個用于數(shù)組的方法,它會對數(shù)組中的每個元素執(zhí)行一次回調(diào)函數(shù)。該方法沒有返回值,它只是遍歷整個數(shù)組并執(zhí)行回調(diào)函數(shù)。
forEach方法的語法如下:
array.forEach(callback(currentValue, index, array), thisArg);
其中,callback是要執(zhí)行的函數(shù),它會被傳入三個參數(shù):
currentValue:當前處理的元素。index:當前處理元素的索引。array:當前正在遍歷的數(shù)組。
thisArg是一個可選參數(shù),用于指定執(zhí)行回調(diào)函數(shù)時使用的 this 值。
forEach方法返回的是undefined,它不會生成新的數(shù)組。
forEach方法和for循環(huán)在功能上類似,但它更簡潔、易讀,也更安全,因為它會避免循環(huán)時的一些常見問題,如數(shù)組越界、重復計算等。
下面是一個使用 forEach 方法遍歷數(shù)組并輸出每個元素的例子:
const arr = [1, 2, 3];
arr.forEach((element) => {
console.log(element);
});
map
map 方法也是一個用于數(shù)組的方法,它會對數(shù)組中的每個元素執(zhí)行一次回調(diào)函數(shù),并將回調(diào)函數(shù)的返回值存儲在一個新的數(shù)組中。
map 方法的語法如下:
array.map(callback(currentValue, index, array), thisArg);
其中,callback 是要執(zhí)行的函數(shù),它會被傳入三個參數(shù):
currentValue:當前處理的元素。index:當前處理元素的索引。array:當前正在遍歷的數(shù)組。
thisArg是一個可選參數(shù),用于指定執(zhí)行回調(diào)函數(shù)時使用的 this 值。
map 方法會返回一個新的數(shù)組,這個數(shù)組的長度和原數(shù)組相同,但是每個元素都是經(jīng)過回調(diào)函數(shù)處理后的結(jié)果。
下面是一個使用 map 方法將數(shù)組中的每個元素都加上 1 的例子:
const arr = [1, 2, 3];
const newArr = arr.map((element) => {
return element + 1;
});
console.log(newArr); // 輸出[2, 3, 4]
可以看到,map 方法生成了一個新的數(shù)組,并將原數(shù)組中的每個元素都加上了 1。
剖析原理
forEach和map方法的原理都是基于數(shù)組的迭代器,實際上它們都是通過調(diào)用迭代器實現(xiàn)對數(shù)組的遍歷。
JavaScript數(shù)組有一個內(nèi)置的迭代器,即Array.prototype[@@iterator]方法。該方法返回一個迭代器對象,可以使用該對象對數(shù)組進行迭代。forEach和map方法都會調(diào)用Array.prototype[@@iterator]方法返回迭代器對象,然后使用該迭代器對象進行遍歷。
forEach
當調(diào)用forEach方法時,JavaScript引擎會執(zhí)行以下步驟:
- 檢查數(shù)組是否存在,如果不存在,則拋出
TypeError異常。 - 檢查第一個參數(shù)是否是一個函數(shù),如果不是,則拋出
TypeError異常。 - 檢查第二個參數(shù)是否是一個對象,如果是,則將該對象作為this值傳遞給回調(diào)函數(shù),否則
this值為undefined。 - 獲取迭代器對象,通過調(diào)用
Array.prototype[@@iterator]方法獲得。 - 對于迭代器對象中的每個元素,依次執(zhí)行回調(diào)函數(shù),并將當前元素的值、索引和原數(shù)組作為參數(shù)傳遞給回調(diào)函數(shù)。
forEach方法不會返回任何值。
下面是一個簡化的forEach實現(xiàn)代碼:
Array.prototype.myForEach = function(callback, thisArg) {
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
for (var i = 0; i < this.length; i++) {
callback.call(thisArg, this[i], i, this);
}
};
可以看到,該實現(xiàn)代碼使用了for循環(huán)來遍歷數(shù)組,并使用call方法調(diào)用回調(diào)函數(shù),并將當前元素的值、索引和原數(shù)組作為參數(shù)傳遞給回調(diào)函數(shù)。
map
map方法的原理與forEach方法類似,也是通過調(diào)用迭代器實現(xiàn)對數(shù)組的遍歷,只不過map方法在遍歷時會將回調(diào)函數(shù)的返回值存儲在一個新的數(shù)組中。下面我們以map方法為例來剖析其原理。
當調(diào)用map方法時,JavaScript引擎會執(zhí)行以下步驟:
- 檢查數(shù)組是否存在,如果不存在,則拋出
TypeError異常。 - 檢查第一個參數(shù)是否是一個函數(shù),如果不是,則拋出
TypeError異常。 - 檢查第二個參數(shù)是否是一個對象,如果是,則將該對象作為
this值傳遞給回調(diào)函數(shù),否則this值為undefined。 - 創(chuàng)建一個新的空數(shù)組,用于存儲回調(diào)函數(shù)的返回值。
- 獲取迭代器對象,通過調(diào)用
Array.prototype[@@iterator]方法獲得。 - 對于迭代器對象中的每個元素,依次執(zhí)行回調(diào)函數(shù),并將當前元素的值、索引和原數(shù)組作為參數(shù)傳遞給回調(diào)函數(shù)。
- 將回調(diào)函數(shù)的返回值存儲在新數(shù)組中。
- 返回新數(shù)組。
下面是一個簡化的map實現(xiàn)代碼:
Array.prototype.myMap = function(callback, thisArg) {
if (typeof callback !== 'function') {
throw new TypeError(callback + ' is not a function');
}
var newArray = [];
for (var i = 0; i < this.length; i++) {
newArray.push(callback.call(thisArg, this[i], i, this));
}
return newArray;
};
可以看到,該實現(xiàn)代碼除了使用for循環(huán)遍歷數(shù)組之外,還創(chuàng)建了一個新的數(shù)組,并將回調(diào)函數(shù)的返回值存儲在新數(shù)組中,最后返回新數(shù)組。
forEach和map的共同點
- 都只能遍歷數(shù)組
- 都是循環(huán)遍歷數(shù)組中的每一項。
- 每次執(zhí)行匿名函數(shù)都支持三個參數(shù),參數(shù)分別為item(當前每一項),index(索引值),arr(原數(shù)組)。
- 匿名函數(shù)中的this都是指向window。
forEach和map的不同點
forEach()方法沒有返回值,會更改原數(shù)組。
map() 有返回值,返回一個新數(shù)組,不會改變原數(shù)組,map() 不會對空數(shù)組進行檢測。
總的來說 map 的速度大于 forEach()
性能上來說for > forEach > map
總結(jié)
總的來說,forEach和map方法都是基于數(shù)組的迭代器實現(xiàn)的,它們的主要區(qū)別在于對回調(diào)函數(shù)的處理方式。forEach方法執(zhí)行回調(diào)函數(shù)時,不會將回調(diào)函數(shù)的返回值存儲起來,而是直接忽略。map方法執(zhí)行回調(diào)函數(shù)時,會將回調(diào)函數(shù)的返回值存儲在一個新數(shù)組中,最后將該數(shù)組返回。因此,如果我們需要對數(shù)組中的每個元素執(zhí)行一個操作,并將操作的結(jié)果存儲在新數(shù)組中,那么應該使用map方法。如果我們只是需要對數(shù)組中的每個元素執(zhí)行一些操作,而不需要將操作的結(jié)果存儲起來,那么應該使用forEach方法。
到此這篇關于JavaScript中forEach和map詳細講解的文章就介紹到這了,更多相關js forEach和map內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
小程序角標的添加及綁定購物車數(shù)量進行實時更新的實現(xiàn)代碼
這篇文章主要介紹了小程序角標的添加及綁定購物車數(shù)量進行實時更新的實現(xiàn)代碼,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-12-12
ie8 不支持new Date(2012-11-10)問題的解決方法
使用JS的時候也碰到了如下問題,后來經(jīng)過修改,在IE8環(huán)境里,下面的代碼是可用的,下面與大家分享下ie8 不支持new Date的解決方法,有類似問題的朋友可以參考下2013-07-07
js清空表單數(shù)據(jù)的兩種方式(遍歷+reset)
這篇文章主要介紹了js清空表單數(shù)據(jù)的兩種方式(遍歷+reset),需要的朋友可以參考下2014-07-07

