JS中Map和ForEach的区别

举报
达拉崩巴斑得贝迪卜多 发表于 2021/12/20 22:54:57 2021/12/20
【摘要】 Map 定义和用法 map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。 map() 方法按照原始数组元素顺序依次处理元素。 注意: map() 不会对空数组进行检测。 ...

Map

定义和用法
map() 方法返回一个新数组,数组中的元素为原始数组元素调用函数处理后的值。

map() 方法按照原始数组元素顺序依次处理元素。

注意: map() 不会对空数组进行检测。

注意: map() 不会改变原始数组。


forEach

定义和用法

forEach() 方法用于调用数组的每个元素,并将元素传递给回调函数。

注意: forEach() 对于空数组是不会执行回调函数的。


forEach()map()两个方法都是ECMA5中Array引进的新方法,用来遍历数组中的每一项,但是它们之间还是有区别的。 但是从本质上还是有很大的区别的,那么我们探探究竟。

forEach()

[1, 2 ,3, 4].forEach(alert);
等同于下面这个for循环:

var array = [1, 2, 3, 4];
for (var i= 0, length = array.length; i< length;i++) {
 alert(array[i]);
}

  
 
  • 1
  • 2
  • 3
  • 4

我们看一下forEach的源码:
在这里插入图片描述
从源码中我们可以看出,forEach方法中的function回调支持3个参数,第1个是遍历的数组内容;第2个是对应的数组索引,第3个是数组本身。

因此,我们有:

[].forEach(function(value, index, array) {
  // ...
});

  
 
  • 1
  • 2
  • 3

map

这里的map不是“地图”的意思,而是指“映射”。[].map(); 基本用法跟forEach方法类似:
我们看一下map的源码:
在这里插入图片描述
callback的参数也类似:

[].map(function(value, index, array) {
  // ...
});

  
 
  • 1
  • 2
  • 3

注意:由于forEachmap都是ECMA5新增数组的方法,所以ie9以下的浏览器还不支持( 不过呢,可以从Array原型扩展可以实现以上全部功能,例如forEach方法:

if (typeof Array.prototype.forEach != "function") {
  Array.prototype.forEach = function() {
    /* 实现 */
  };
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5

区别:

举例说明:

var arr = ['10', '9', '8'];

var result = arr.forEach(((value, index, array) => {
    return value*2
}));
// forEach:用来遍历数组中的每一项;这个方法执行是没有返回值的,对原来数组也没有影响;
console.log('返回值',result); // 返回值 undefined
console.log('原数组',arr); // 原数组 [ '10', '9', '8' ]

var mapResult = arr.map((value,index,array)=>{
    return value*2
}).sort((x,y)=>{
    return x-y
});
console.log(mapResult); // [ 20, 18, 16 ] 返回一个新数组  [ 16, 18, 20 ]  排序
console.log(arr); // [ '10', '9', '8' ] 原数组没有改变

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

1、map速度比forEach快

2、map会返回一个新数组,不对原数组产生影响,foreach不会产生新数组,forEach返回undefined

3、map因为返回数组所以可以链式操作,forEach不能

4, map里可以用return(return的是什么,相当于把数组中的这一项变为什么(并不影响原来的数组,只是相当于把原数组克隆一份,把克隆的这一份的数组中的对应项改变了) ,而forEach里用return不起作用,forEach不能用break,会直接报错


那么接下来,我继续做分析,为什么更推荐用.map(),而不是.forEach()?

首先,.map()要比.forEach()执行速度更快。虽然我也说过执行速度不是我们需要考虑的主要因素,但是他们都比for()要更好用,那肯定要选更优化的一个。

map()适用于你要改变数据值的时候。不仅仅在于它更快,而且返回一个新的数组。这样的优点在于你可以使用复合(composition)(map(), filter(), reduce()等组合使用)来玩出更多的花样。

第二,.forEach()的返回值并不是array。如果你想用函数式编程写个链式表达式,.map()将会是你不二的选择。

forEach适合于你并不打算改变数据的时候,而只是想用数据做一些事情 – 比如存入数据库或则打印出来。

最后,感谢大家耐心的阅读,排个序

.map() > .forEach() > for()


不管是forEach还是map在IE6-8下都不兼容(不兼容的情况下在Array.prototype上没有这两个方法),那么需要我们自己封装一个都兼容的方法,代码如下:

兼容写法:

/**
* forEach遍历数组
* @param callback [function] 回调函数;
* @param context [object] 上下文;
*/
Array.prototype.myForEach = function myForEach(callback,context){
    context = context || window;
    if('forEach' in Array.prototye) {
        this.forEach(callback,context);
        return;
    }
    //IE6-8下自己编写回调函数执行的逻辑for(var i = 0,len = this.length; i < len;i++) {
        callback && callback.call(context,this[i],i,this);
    }
}
/**
* map遍历数组
* @param callback [function] 回调函数;
* @param context [object] 上下文;
*/
Array.prototype.myMap = function myMap(callback,context){
    context = context || window;
    if('map' in Array.prototye) {
        return this.map(callback,context);
    }
    //IE6-8下自己编写回调函数执行的逻辑var newAry = [];
    for(var i = 0,len = this.length; i < len;i++) {
        if(typeof  callback === 'function') {
            var val = callback.call(context,this[i],i,this);
            newAry[newAry.length] = val;
        }
    }
    return newAry;
}

  
 
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36

文章来源: lvsige.blog.csdn.net,作者:祥子的小迷妹,版权归原作者所有,如需转载,请联系作者。

原文链接:lvsige.blog.csdn.net/article/details/108514832

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。