for语句在js刚出来的时候,就已经存在了,而map和forEach这两个方法都是ES5时出来的,前者为语句,后者为方法。map和forEach这两个方法,都需要传递参数,并且该参数是一个回调函数,所以,单纯的从性能上讲,map和forEach方法是远远落后for语句的。
既然map和forEach性能没有for好,那么为什么在ES5时,设计出这两个方法?
答案是作用域保存数据的问题。
看下面的代码:
<input type="button" value="a" />
<input type="button" value="b" />
<input type="button" value="c" />
<script>
var arr=document.getElementsByTagName("input"), i=0, len=arr.length;
for( ; i<len; i++ ){
arr[i].onclick = function(){
alert( i );
}
}
</script>
你觉得上面的代码,当点击b那个按钮时,输出的是什么?
你可能觉得输出的是1啊,很简单啊,但答案实际上是2,原因是i是全局变量,根据代码的执行顺序,当点击按钮的时候,for循环早就执行完了,那么i就是2。
如果程序这样写呢?
Array.from(arr).forEach( (btn, ind)=>{
btn.onclick = ()=>{
alert( ind );
}
} );
点击哪一个按钮,就会对应输出这个按钮的下标。因为forEach方法里面,参数部分的那个回调函数,数组成员有多少个,它就执行多少次,函数是存在作用域的,btn和ind都是这个函数的局部变量,所以循环时,彼此没有任何影响。
所以,很多时候,用forEach来实现循环,会更方便一点,但性能确实比for语句差很多。
map方法和forEach方法类似,都是对数组进行循环,数组中每一个成员,都被其回调函数处理一次。区别在于map有返回值,而forEach没有返回值。
var arr = [1,2,3,4,5];
var r = arr.map( (v, i)=>{
return v*2;
} );
console.log(r); // [2,4,6,8,10]
如果在上文代码中,将map换为forEach,那么r的结果就是undefined,其他没区别,所以性能上map稍落后于forEach。
来源:千锋HTML5