JS中Map和ForEach的区别
定义和⽤法
map() ⽅法返回⼀个新数组,数组中的元素为原始数组元素调⽤函数处理后的值。
map() ⽅法按照原始数组元素顺序依次处理元素。
注意: map() 不会对空数组进⾏检测。
注意: map() 不会改变原始数组。
定义和⽤法
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]);
}
我们看⼀下forEach的源码:
从源码中我们可以看出,forEach⽅法中的function回调⽀持3个参数,第1个是遍历的数组内容;第2个是对应的数组索引,第3个是数组本⾝。
因此,我们有:
[].forEach(function(value, index, array){
// ...
});
map
这⾥的map不是“地图”的意思,⽽是指“映射”。[].map(); 基本⽤法跟forEach⽅法类似:
我们看⼀下map的源码:
callback的参数也类似:
[].map(function(value, index, array){
// ...
});
注意:由于forEach、map都是ECMA5新增数组的⽅法,所以ie9以下的浏览器还不⽀持( 不过呢,可以从Array原型扩展可以实现以上全部功能,例如forEach⽅法:
if(typeof Array.prototype.forEach !="function"){
Array.prototype.forEach = function(){
/* 实现 */
};
}
区别:
举例说明:
var arr =['10', '9', '8'];
var result = arr.forEach(((value, index, array)=> {
return value*2
}));
/
/ forEach:⽤来遍历数组中的每⼀项;这个⽅法执⾏是没有返回值的,对原来数组也没有影响;
console.log('返回值',result); // 返回值 undefined
sort函数 jsconsole.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、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]上下⽂;
*/
ForEach =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]上下⽂;
*/
Map =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;
}
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论