[譯]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.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM