美文网首页
javascript的map和forEach,for性能比较

javascript的map和forEach,for性能比较

作者: 上海老宅男 | 来源:发表于2020-09-08 15:53 被阅读0次

    for–速度最快,forEach和for++次之相当,map慢
    原因:从源码看出,map需要有回调函数的返回值,并且新建一个和遍历数组一样长度的数组作为返回,forEach则没有这些开销

    注:map,forEach不能使用break跳出整个循环,不能使用continue跳出本次循环。使用retrun相当于for中的continue的作用,从源码可以看出,结束本次循环的回调函数

    console.time('map');
    for (var i = 0; i < 100000; i++) {
        var s = new Array(1000).fill('1')
        var arr = s.map((item, idx)=>{
            return item; 
        });
    }
    console.timeEnd('map');
    
    console.time('foreach');
    for (var i = 0; i < 100000; i++) {
        var arr2 = [];
        var s2 = new Array(1000).fill('1');
        s2.forEach((item, idx)=>{
            arr2[idx] = item;
        });
    }
    console.timeEnd('foreach');
    
    console.time('for++');
    for (var i = 0; i < 100000; i++) {
        var arr3 = [];
        var s3 = new Array(1000).fill('1')
        for(var idx = 0; idx < s3.length; idx++){
            arr3[idx] = s3[idx]; 
        };
    }
    console.timeEnd('for++');
    
    console.time('for--');
    for (var i = 0; i < 100000; i++) {
        var arr4 = [];
        var s4 = new Array(1000).fill('1')
        for(var idx = s4.length-1; idx >=  0; idx--){
            arr4[idx] = s4[idx]; 
        };
    }
    console.timeEnd('for--');
    map: 2064.2978515625ms
    18 foreach: 1154.373046875ms
    for++: 969.011962890625ms
    for--: 709.780029296875ms
    
    

    forEach实源码:

    Array.prototype.foreach = function(callback, thisArg) {
        var T, k;
        if (this == null) {
          throw new TypeError(' this is null or not defined');
        }
        var O = Object(this);//拿到变量的数组
        var len = O.length >>> 0;//右移的作用,所有非数值转换成0,所有大于等于0数取整数部分
        if (typeof callback !== "function") {
          throw new TypeError(callback + ' is not a function');
        }
        if (arguments.length > 1) {
          T = thisArg;//如果存在第三个参数,表明this的指向
        }
        k = 0;
        while (k < len) {
          var kValue;
          if (k in O) //k为属性名
            kValue = O[k];
            callback.call(T, kValue, k, O);
          }
          k++;
        } 
     }
    
    

    map实现源码:

    Array.prototype.map = function(callback, thisArg) {
        var T, A, k;
        if (this == null) {
          throw new TypeError(" this is null or not defined");
        }
        var O = Object(this);
        var len = O.length >>> 0;
        if (Object.prototype.toString.call(callback) != "[object Function]") {
          throw new TypeError(callback + " is not a function");
        }
        if (thisArg) {
          T = thisArg;
        }
        A = new Array(len);
        k = 0;
        while(k < len) {
          var kValue, mappedValue;
          if (k in O) {
            kValue = O[ k ];
            mappedValue = callback.call(T, kValue, k, O);
            A[ k ] = mappedValue;
          }
          k++;
        }
        return A;//返回新的数组,长度和原数组一样
      }; 
    

    执行速度对比

    jsPref是一个非常好的网站用来比较不同的JavaScript函数的执行速度。

    这里是forEach()和map()的测试结果:

    image

    可以看到,在我到电脑上forEach()的执行速度比map()慢了70%。每个人的浏览器的执行结果会不一样。你可以使用下面的链接来测试一下: Map vs. forEach - jsPref。

    JavaScript太灵(gui)活(yi)了,出了BUG你也不知道,不妨接入Fundebug线上实时监控。

    函数式角度的理解

    如果你习惯使用函数是编程,那么肯定喜欢使用map()。因为forEach()会改变原始的数组的值,而map()会返回一个全新的数组,原本的数组不受到影响。

    哪个更好呢?

    取决于你想要做什么。

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

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

    我们首先使用map将每一个元素乘以2,然后紧接着筛选出那些大于5的元素。最终结果赋值给arr2。

    核心要点

    能用forEach()做到的,map()同样可以。反过来也是如此。

    map()会分配内存空间存储新数组并返回,forEach()不会返回数据。

    forEach()允许callback更改原始数组的元素。map()返回新的数组。

    相关文章

      网友评论

          本文标题:javascript的map和forEach,for性能比较

          本文链接:https://www.haomeiwen.com/subject/qrfjektx.html