一、定义
我们首先来看一看 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())
}
}
}