Статьи

Производительность JavaScript: Array.prototype против []

Array.prototype содержит много общих методов, которые можно применять к объектам, подобным массиву . [] является популярным ярлыком для доступа к этим методам. В этом посте рассматриваются плюсы и минусы использования этого ярлыка.

Обновление: Вдохновленный комментарием Кевина Робертса, я добавил третий способ доступа к общим методам и заключение.

Пояснения

Объекты, подобные массиву. Некоторые объекты в JavaScript являются
массив типа , они проиндексированы доступ и свойство длины как массивы, но ни один из методов массива. Подобные массиву объекты включают в себя специальные переменные аргументы (дающие индексированный доступ ко всем аргументам, переданным функции) и большинство результатов DOM. Отсутствие стандартных методов массива особенно прискорбно в ECMAScript 5, в котором есть такие полезности, как Array.prototype.forEach.

Универсальные методы. Некоторые методы являются общими . Хотя они непосредственно доступны экземплярам своего прототипа, они также могут быть заимствованы другими экземплярами. Чтобы заимствовать универсальный метод, вызывается один из следующих двух методов:

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

Экземпляр заимствования является первым аргументом и становится его значением. Общие методы должны быть написаны так, чтобы они требовали, чтобы они имели только минимальный набор методов. Например, большинству универсальных методов массива это нужно только для обеспечения длины и индексированного доступа. Array.prototype.slice является универсальным и позволяет превратить любую часть объекта, подобного массиву, в массив.

Пример: общий вызов 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. То есть вы получаете доступ к свойству прототипа через экземпляр.

  • Pro: более компактный.
  • Con: На самом деле не описывает свои намерения. Вы не пытаетесь вызвать метод экземпляра, вы заимствуете функцию из прототипа.
  • Против: Немного медленнее (см. Ниже).

Сроки нескольких способов доступа к универсальным методам

Я хотел посмотреть, насколько сильно пострадали плохие показатели, и быстро провел ненаучный тест. Тестовая структура:

    var iterations = 100000000;
    var data = []; // empty so that slice() doesn’t have much to do
    (function () {
        var start = (new Date).getTime();
        
       // loop

        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, Intel Core i5 с частотой 2,7 ГГц):

  итерации опытный образец сокращенный быстрый прототип
Node.js 0.4.8 100000000 5019ms 5075ms 4692ms
Firefox 6 10000000 1592ms 2237ms 1522ms
Rhino 1.7 выпуск 3 10000000 2318ms 2687ms 1878ms

Вывод

Разница во времени не совсем потрясающая. Таким образом, если вы не работаете с критичным к производительности кодом, вы должны выбрать то, что, по вашему мнению,
лучше всего
читается (в отличие от того, что легче всего писать).

 

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