一、定義
我們首先來看一看 MDN 上對 Map 和 ForEach 的定義:
forEach()
: 針對每一個元素執行提供的函數(executes a provided function once for each array element)。map()
: 創建一個新的數組,其中每一個元素由調用數組中的每一個元素執行提供的函數得來(creates a new array with the results of calling a provided function on every element in the calling array)。
到底有什么區別呢?forEach()
方法不會返回執行結果,而是undefined
。也就是說,forEach()
會修改原來的數組。而map()
方法會得到一個新的數組並返回。
二、相同點:
- 都是循環遍歷數組中的每一項
- forEach和map方法里每次執行匿名函數都支持3個參數,參數分別是item(當前每一項)、index(索引值)、arr(原數組)
- 匿名函數中的this都是指向window
- 只能遍歷數組
三、示例
1、Map
1.1、map 接收兩個參數:callback 函數,它會在 map 執行之后被觸發。上下文變量,即執行 callback 函數時 this 指向的對象。map 會返回一個新數組。
map(callback[, thisArg]) [1, 2, 3, 4, 5].map(
function(value, index, originalArray) {
console.log(`${index}: ${value} / ${originalArray} /`);
console.log(this);
return value + 1;
},
{ selfObj: 1 });
// 0: 1 / 1,2,3,4,5 / {selfObj: 1}
// 1: 2 / 1,2,3,4,5 / {selfObj: 1}
// 2: 3 / 1,2,3,4,5 / {selfObj: 1}
// 返回值:[2, 3, 4, 5, 6]
|
1.2、注意:map 的返回不等於原數組,如果你習慣使用函數是編程,那么肯定喜歡使用map(),
因為forEach()
會改變原始的數組的值,而map()
會返回一個全新的數組,原本的數組不受到影響。使用map優點在於你可以使用復合(composition)(map(), filter(), reduce()等組合使用)來玩出更多的花樣。
2、forEach
2.2、 forEach 接收的參數和 map 相同,但是它沒有返回值,即它返回的是 undefined。
[1, 2, 3, 4, 5].forEach(
function(value, index, originalArray) {
console.log(`${index}: ${value} / ${originalArray} /`);
console.log(this);
},
{ selfObj: 1 });
// 0: 1 / 1,2,3,4,5 / {selfObj: 1}
// 1: 2 / 1,2,3,4,5 / {selfObj: 1}
// 2: 3 / 1,2,3,4,5 / {selfObj: 1}
// 返回值:undefined
結束循環: var arr = [1,2,3]; arr.forEach(function(value,index) { if(index === 1) return false; console.log(arr[index]) });
|
四、中斷
1、中斷:return false ,結束本次循環,進入下一次循環
注意:異步函數執行上map和forEach相同,await不生效 循環里不能有break或continue, 會產生報錯 callback的return 返回新的數組元素,不使用return時等價於返回undefined。
總結:
(1) for:當沒有label標記時候,break跳出本次循環並執行循環體后的代碼,continue結束本次循環執行下一次循環。沒有return。
(2) Array.forEach:遍歷整個數組,return false或者true都是結束本次循環執行下一次循環。沒有break || continue。
(3) Array.map:map和forEach類似,有返回值,返回結果是return 值組成的數組。
(4) for...in:會忽略break || continue。沒有return。
(5) for...of:break跳出本次循環並執行循環體后的代碼,continue結束本次循環執行下一次循環,和for一樣。注意:for(var v in arr)
v是數組值!。
(6) Jquery.each: return false跳出本次循環並執行循環體后的代碼;return true結束本次循環執行下一次循環。沒有break || continue。
開發過程中,根據使用場景,有些可以並行執行,有些情況需要依次執行一組異步函數。可以封裝一個方法來執行。
/*
* 並行執行一組方法
* @params {Array<Object>} funcArr 一組待執行的函數{func: asyncFunc, params: funcParams}
* @returns {Array<Promise>} 函數執行結果(按數組順序返回)
* @example
* excuteInParallel([{func: asynFuc1, params: 2},{func: asynFuc2, params: {param: 1}}}])
* */
let ret = []
async function excuteInParallel (funcArr = []) {
const result = funcArr.map((item) => {
if (item.params) {
return item.func(item.params)
}
return item.func()
})
return Promise.all(result)
}
/*
* 串行執行一組異步方法
* @params {Array<Object>} funcArr 一組待執行的函數{func: asyncFunc, params: funcParams}
* @returns {Array<Promise>} 函數執行結果(按數組順序返回)
* @example
* excuteInParallel([{func: asynFuc1, params: 2},{func: asynFuc2, params: {param: 1}}}])
* */
async function excuteInSeries (funcArr = []) {
const result = []
for (const item of funcArr) {
if (item.params) {
result.push(await item.func(item.params))
} else {
result.push(await item.func())
}
}
}