for循环、forEach、map、filter区别及效率分析

2021年1月14日 65点热度 0条评论 来源: YiCheng_L

        遍历数组最常用到的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++){
        code...
    }

        取完平均值是7.3ms

        优化过的for循环,

    for(var i = 0,len = testData.length; i < len; i++){
        code...
    }

        取完平均值是2.7ms

        但是当x = 99999,到达10^5级时,遍历时间分别是7ms和7.1ms,二者几乎没有差别;当 x = 999999时,遍历时间分别是,14.1ms和14.6ms,前者循环耗时比后者要少,即遍历数据从10^5级别开始普通for循环想关闭优化的for循环效率更高。

    forEach方法

      摘自: http://www.runoob.com/jsref/jsref-foreach.html

参数 描述
function(currentValue, index, arr) 必需。 数组中每个元素需要调用的函数。
函数参数:

参数 描述
currentValue 必需。当前元素
index 可选。当前元素的索引值。
arr 可选。当前元素所属的数组对象。
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方法

      摘自: http://www.runoob.com/jsref/jsref-map.html

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方法

      摘自: http://www.runoob.com/jsref/jsref-filter.html

参数 描述
function(currentValue, index,arr) 必须。函数,数组中的每个元素都会执行这个函数
函数参数:

参数 描述
currentValue 必须。当前元素的值
index 可选。当前元素的索引值
arr 可选。当前元素属于的数组对象
thisValue 可选。对象作为该执行回调时使用,传递给函数,用作 "this" 的值。
如果省略了 thisValue ,"this" 的值为 "undefined"

  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%左右。

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

 

 

 

 

 

 

 

 

 

 

 

forEach方法    
10^4级  2.5ms 10^5级  4ms 10^6级  6.7ms
     

 

 

 

 

 

 

 

    原文作者:YiCheng_L
    原文地址: https://blog.csdn.net/YiCheng_L/article/details/77141669
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系管理员进行删除。