一、定义

我们首先来看一看 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) { 
${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}
: 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}
: 1}
 // 返回值:undefined
 
结束循环: 
var arr = [1,2,3]; 
arr.forEach(function(value,index) { 
index === 1) return false; 
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())
     }
  }
  }