• [译]JavaScript:Array.prototype和[]的性能差异


    原文:http://www.2ality.com/2011/08/array-prototype-performance.html


    Array.prototype包含了许多的通用方法,这些通用方法可以使用在任意的类数组对象上.[]是一个常用的用来访问这些方法的快捷方式.本文要讲的就是使用这个快捷方式的优点和缺点.

    说明

    类数组(array-like)对象.JavaScript中有一些对象叫类数组对象,他们有索引访问,有length属性,和数组很像,却没有数组的方法.常见的类数组对象有:特殊值arguments(能够通过索引访问到传入一个函数调用中的所有参数)和大部分的DOM查询结果.在ECMAScript 5中,不能使用标准的数组方法是多么的不幸,比如很有用的Array.prototype.forEach方法.

    通用方法(Generic methods).有一些方法是通用的.这些方法不光可以被属于他们原型的实例调用,还可以被其他类型的对象实例借来调用.想要借用一个通用方法,可以在这个通用方法上调用下面的这两个方法:

    • Function.prototype.call(thisValue, [arg1], [arg2], ...)
    • Function.prototype.apply(thisValue, [arrayWithArguments])

    借用方法的对象实例要放在第一个参数的位置,作为这个通用方法调用时的this值.通用方法都对借用该方法的对象实例有一定的要求.比如,大部分通用的数组方法只允许那些拥有索引访问和length属性的对象实例借用自己. Array.prototype.slice是个通用方法,它可以把一个类数组对象的全部或部分成员转换成数组.

    例子: 在一个类数组对象arguments上调用通用方法Array.prototype.map().

    function prefixHello(prefix) {
        return Array.prototype.map.call(arguments, function(elem) {
            return "Hello "+elem;
        });
    }

    执行:

    > prefixHello("Jane", "John")
    [ 'Hello Jane', 'Hello John' ]

    [] 作为快捷方式. [].foo经常作为Array.prototype.foo的快捷方式.也就是说,你可以通过一个对象实例访问到了原型上的方法.

    • 优点: 更简洁.
    • 缺点: 并不能真正说明自己的意图.因为你并不是真的在调用一个实例方法,而是在借用原型上的一个函数.
    • 缺点: 稍微慢点.

    访问通用方法的几种方式,哪种最快?

    我想看看到底性能有多大的差别,于是做了一个不是很科学的测试.测试代码:

    var iterations = 100000000;
    var data = []; // 空数组,更快
    (function () {
        var start = (new Date).getTime();
        
        // 循环
    
        var diff = (new Date).getTime() - start;
        console.log(diff);    
    }());

    直接访问原型上的方法:

    for(var i=0; i<iterations; i++) {
        Array.prototype.slice.call(data);
    }

    访问实例[]上的方法:

    for(var i=0; i<iterations; i++) {
        [].slice.call(data);
    }

    把原型缓存在一个局部变量里:

    var arrayProto = Array.prototype;
    for(var i=0; i<iterations; i++) {
        arrayProto.slice.call(data);
    }

    结果(iMac, 2.7 GHz Intel Core i5):

     测试环境 循环次数 直接访问原型 访问快捷方式[] 访问缓存原型的变量
    Node.js 0.4.8 100,000,000 5019ms 5075ms 4692ms
    Firefox 6 10,000,000 1592ms 2237ms 1522ms
    Rhino 1.7 release 3 10,000,000 2318ms 2687ms 1878ms

    结论

    从结论可以看出,几种方法在执行时间上并没有太大的差别.因此,除非你写的代码非常重视性能,否则,你应该使用你认为可读性最好的方式(对应的就是写起来最简洁的方式).

    译者注:最常用的通用方法Array.prototype.slice,只有jQuery用的是[].slice的形式,prototype,mootools,yui,dojo使用的都是Array.prototype.slice.

  • 相关阅读:
    Java 8 lambda maxBy取最大/minBy取最小取平均值counting计数partitioningBy分隔/groupingBy分组
    mybatis xml参数传递详解
    java中判断字符串是否为纯数字,正则表达式判断
    OAuth 2.0 的四种方式
    Spring Boot 日志配置(超详细)
    SpringBoot基础系列-使用日志
    zuul动态配置路由规则,从DB读取
    TypeError: this.getOptions is not a function
    mysql索引类型和索引方法
    SpringBoot 处理异常的几种常见姿势
  • 原文地址:https://www.cnblogs.com/ziyunfei/p/2698505.html
Copyright © 2020-2023  润新知