美文网首页
深聊JS数组中的forEach和map方法

深聊JS数组中的forEach和map方法

作者: 空无一码 | 来源:发表于2019-03-13 23:24 被阅读34次

    在和团队分享Airbnb的eslint规则时,当我们讨论 no-param-reassign 的时候,在项目的代码中用到了forEach 方法,场景如下:

    const demoFunc = (arr) => {
      arr.forEach((item) = > {
        item.name = 'coder';
      });  
    }
    

    因为改变了函数的形参,所以报了eslint的错误,这引起了我们对forEach方法的重视,同时也让我们想到了另一很类似的map方法,对于有追求的码农,当然要写篇文章深入剖析有关的知识。

    forEach()和map()两个方法都是ECMA5中Array引进的新方法,主要作用都是对数组的每个元素执行一次提供的函数,但他们还是有区别的。

    map()

    map方法将数组的所有成员依次传入参数函数,然后把每一次的执行结果组成一个新数组返回。

    const arr = [1, 2, 3];
    const newArr = arr.map(item => item + 1);
    
    console.log(arr); // [ 1, 2, 3 ]
    console.log(newArr); // [ 2, 3, 4 ]
    

    上面代码中,arr数组的所有成员依次执行参数函数,运行结果组成一个新数组返回,原数组没有变化。

    forEach()

    forEach方法与map方法很相似,也是对数组的所有成员依次执行参数函数。但是,forEach方法不返回值,只用来操作数据。

    这就是说,如果数组遍历的目的是为了得到返回值,那么使用map方法,否则使用forEach方法。

    const arr = [1, 2, 3];
    const newArr = arr.forEach(item => item + 1);
    
    console.log(arr); // [ 1, 2, 3 ]
    console.log(newArr); // undefined
    

    可以看到,newArr为undefined,说明forEach方法不返回值。

    注意,forEach方法无法中断执行,总是会将所有成员遍历完。如果希望符合某种条件时,就中断遍历,要使用for循环。

    forEach和map方法 能改变原数组吗?

    可以看到上面的例子,对于数组元素为基础类型的数组,forEach和map方法 并不能改变原数组,但是当元素为对象时:

    const arr = [{ name: 'coder' }, { name: 'coder' }, { name: 'coder' }];
    const newArr = arr.forEach(item => item.name = 'newName');
    
    console.log(arr); 
    // [ { name: 'newName' }, { name: 'newName' }, { name: 'newName' } ]
    console.log(newArr);  // undefined
    

    可以看到,对于元素为对象的数组,再使用forEach()方法时,虽然依然没有返回值,但原数组的元素却是可以改变的。

    const arr = [{ name: 'coder' }, { name: 'coder' }, { name: 'coder' }];
    const newArr = arr.map(item => item.name = 'newName');
    
    console.log(arr); 
    // [ { name: 'newName' }, { name: 'newName' }, { name: 'newName' } ]
    console.log(newArr);  
    // [ 'newName', 'newName', 'newName' ]
    

    可以看到,对于元素为对象的数组,再使用map()方法时,原数组的元素也是可以改变的,但是返回的新数组却不是由对象元素组成的。

    结语

    可以看到,即使是我们常用到的forEach和map方法,也是有很多可以深入的地方,特别是当数组元素为引用类型时,是可以改变数组本身的。

    而且map()方法返回的新数组和原数组也是有区别的,可见eslint的代码检查则能提醒我们要清楚知道自己所写代码的意图,防止未知错误的发生。

    相关文章

      网友评论

          本文标题:深聊JS数组中的forEach和map方法

          本文链接:https://www.haomeiwen.com/subject/ftgxmqtx.html