Полезно ли замыкание для разыменования переменных? - PullRequest
11 голосов
/ 28 ноября 2011

Я не уверен, полезно ли или когда (для повышения производительности) разыменовывать переменные.

var x = a.b.c.d[some_key].f;
while (loop) {
    do_something_with(x);
}

кажется лучше, чем

while (loop) {
    do_somthing_with(a.b.c.d[some_key].f);
}

Это нужно или это делается автоматически с помощью умных движков JavaScript?

Но мой вопрос заключается в том, должен ли я сделать это, например, в библиотеке.

(function() {
    var slice = Array.prototype.slice;

    Function.prototype.x = function x() {
        var args = slice.call(arguments, 0);
        ...
    };
})();

или просто

Function.prototype.x = function x() {
    var args = Array.prototype.slice.call(arguments, 0);
    ...
};

Двигатель не может улучшить это автоматически, потому что он не знает, может ли Array.prototype.slice измениться во время работы.

Итак: делает ли замыкание для создания локальной ссылки на функцию слайса сценарий быстрее? Или дополнительная область замыкания делает его медленнее, чем доступ к свойству "slice" свойства "prototype" Array?

Ответы [ 3 ]

10 голосов
/ 28 ноября 2011

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

Tbh, "современные" браузеры действительно оптимизируют доступ довольно много. Все современные движки js используют внутренние справочные таблицы для доступа к свойствам. Тем не менее, вы все еще хотите кэшировать эти глубоко вложенные вещи, так как в старых механизмах он проходил весь путь через все вовлеченные объекты для его решения.

Еще одна причина использовать локальные кэшированные ссылки в том, что даже современные движки js не будут использовать поиск по хешу, как только будет использован какой-то явный или неявный механизм eval.

Особенно Internet Explorer <9 и Firefox 3.5 несут ужасные потери производительности с каждым дополнительным шагом в (прототип) цепочке. </p>


Одно слово предостережения: не очень рекомендуется использовать локальное кэширование для методов объекта (как вы делаете с методом slice). Многие объекты используют this для определения контекста, в котором они вызваны. Хранение метода в локальной переменной приводит к привязке this к global object или null. Поэтому всегда вызывайте такой метод с method.call, чтобы установить контекст вручную.

2 голосов
/ 28 ноября 2011

Если вы собираетесь обращаться к свойству более одного раза, рассмотрите возможность присвоения его локальной переменной. Однако для современных движков javascript такие микрооптимизации мало что дадут, главное - написать код, выражающий ваши намерения.

0 голосов
/ 28 ноября 2011

Для этой конкретной проблемы вам все равно нужна функция утилиты:

function toArray( arrayLike ) {
    return Array.prototype.slice.call( arrayLike );
}

... или если вы заботитесь о производительности:

var toArray = (function () {
    var slice = Array.prototype.slice;

    return function ( arrayLike ) {
        return slice.call( arrayLike );
    };
})();

У вас нетне хочу, чтобы эта slice.call конструкция была во всем вашем коде ...

...