for循环、forEach、map、filter区别及效率分析
遍历数组最常⽤到的for循环,是最为熟知的⼀种⽅法,在ES5中定义了⼀些新的遍历⽅法,更加适⽤于函数式编程,究竟其⽤法区别在哪,以及效率如何,接着下来亲⾃做个测试看⼀下。在Script中写⼊,
var testData = [];//数组初始化
var x = 9999;
for(var i = 0; i < x; i++){
testData[i] = i;
}
在每个遍历开始前和结束后取时间戳的差值,每个测试10次取平均值查看结果。以下测试结果基于Google浏览器。
for循环
for循环是很常见的⼀种循环⽅式,鄙⼈不才,认为for循环只需要注意⼀点即可,
for (s1;s2;s3){
代码块...
}
表达式s3是在代码块执⾏完成之后执⾏的。
对于普通的for循环来说,
for(var i = 0; i < testData.length; i++){
<
}
取完平均值是7.3ms
优化过的for循环,
for(var i = 0,len = testData.length; i < len; i++){
<
}
取完平均值是2.7ms
但是当x = 99999,到达10^5级时,遍历时间分别是7ms和7.1ms,⼆者⼏乎没有差别;当 x = 999999时,遍历时间分别
是,14.1ms和14.6ms,前者循环耗时⽐后者要少,即遍历数据从10^5级别开始普通for循环想关闭优化的for循环效率更⾼。
forEach⽅法
参数描述
function(currentValue, index, arr)必需。 数组中每个元素需要调⽤的函数。
函数参数:
参数描述
currentValue必需。当前元素
index可选。当前元素的索引值。
arr可选。当前元素所属的数组对象。可选。传递给函数的值⼀般⽤ "this" 值。
thisValue 可选。传递给函数的值⼀般⽤ "this" 值。
如果这个参数为空, "undefined" 会传递给 "this" 值
forEach没有返回值
var a = [1,2,3,4,5,6,7,8,9,10];
a.forEach(function(){
console.log(arguments);
}, this);
在回调函数中打印⼀下arguments值,可以看到有三个参数,参数⼀是当前遍历到的值,参数⼆是数组索引值,参数三则是数组本⾝,⾄于this值,还没搞清楚具体作⽤。
怎么停⽌forEach循环呢?
⾸先尝试了break,
var a = [1,2,3,4,5,6,7,8,9,10];
a.forEach(function(val, idx, arr){
if(val == 5)
break;
}, this);
尝试使⽤continue也是同样的错误,这两个关键字只能在循环语句中使⽤,现在是在函数中,不能使⽤。
然后尝试了return false,
var a = [1,2,3,4,5,6,7,8,9,10];
a.forEach(function(val, idx, arr){
console.log(arguments);
return false;
}, this);
循环没有停⽌,return false在函数中使⽤只是阻⽌了当前的函数继续执⾏,并不能阻断遍历过程。
最后尝试异常,
try{
var a = [1,2,3,4,5,6,7,8,9,10];
a.forEach(function(val, idx, arr){
if(val == 5)
throw new Error('break')
}, this);
}catch (e){
console.log(e);
}
循环停⽌了。
testData..forEach(function(v,i,a) { a[i]++;});
取完平均值是2.1ms,x = 99999时,取值8.9ms,x = 999999时,取值39ms,由此可见,在10^4级别及以下forEach的效率占有绝对优势,但从10^5级别开始就⾛下坡了了。然⽽⽤⽕狐测过以后,结果却截然不同(见页底)。
map⽅法
function(currentValue, index,arr)必须。函数,数组中的每个元素都会执⾏这个函数
函数参数:
参数描述
currentValue必须。当前元素的值
index可选。当前元素的索引值
arr可选。当前元素属于的数组对象
thisValue 可选。对象作为该执⾏回调时使⽤,传递给函数,⽤作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"
map⽅法有返回值
从结构和参数形式上看,map⽅法和forEach⽅法⼀模⼀样,但是其区别就在于,forEach⽅法,旨在处理单个数据,map⽅法,旨在整理整体数据,并返回整理后的数据。
var a = [1,2,3,4,5,6,7,8,9,10];
console.log(a.map(function(val, idx, arr){
return val*val;
}, this));
返回单个数据的平⽅,得到了⼀个新数组,每个数组的值都是原数组值的平⽅。
a.map(function(v,i,b) { b[i]++;});
传递给map()函数的调⽤⽅式和传递给forEach()函数的调⽤⽅式⼀样,但传递给map()函数应该有返回值。耗时是在Google浏览器环境下forEach⽅法的基础上相应增加的。
filter⽅法
参数描述
Google for循环 普通for循环
10^4级 7.3ms 10^5级 7ms
10^6级 14.1ms
优化for循环
10^4级 2.7ms 10^5级 7.1ms 10^6级 14.6ms forEach⽅法
10^4级 2.2ms 10^5级 10.1ms 10^6级 41.3ms Firefox for循环 普通for循环
10^4级 2.4ms
10^5级 3.1ms
10^6级 9ms
优化for循环
10^4级 2.4ms 10^5级 3.1ms 10^6级 8.9ms
function(currentValue, index,arr)
必须。函数,数组中的每个元素都会执⾏这个函数函数参数:参数
描述
currentValue 必须。当前元素的值index 可选。当前元素的索引值arr
可选。当前元素属于的数组对象
thisValue
可选。对象作为该执⾏回调时使⽤,传递给函数,⽤作 "this" 的值。如果省略了 thisValue ,"this" 的值为 "undefined"
filter有返回值filter过滤对象数组
从结构和参数形式上看,filter⽅法和map⽅法, forEach⽅法⼀模⼀样,但⽤法是有区别的。 filter作为⼀个过滤器,顾名思义,旨在过滤数据,返回的是满⾜条件的数据。
var a = [1,2,3,4,5,6,7,8,9,10];
console.log(a.filter(function(val, idx, arr){ return val > 5;
}, this));
返回的新数组中的元素都是满⾜⼤于5这个条件的原数组中的元素。
a.filter(function(v,i,b) { b[i]++;});
filter()⽅法返回的数组元素是调⽤的数组的⼀个⼦集,传递的函数⽤来进⾏逻辑判定的,该函数返回true或false,同样的的式⼦,耗时在Google浏览器环境下相⽐较是map⽅法的40%左右。
forEach⽅法
10^4级 2.5ms10^5级 4ms10^6级 6.7ms
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论