Полезно ли замыкание для разыменования переменных?


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

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 более быстрым сценарий? Или дополнительная область закрытия делает его медленнее, чем доступ к свойству "срез" свойства "прототип" массива?

3 11

3 ответа:

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

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

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

Особенно Internet Explorer


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

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

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

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 конструкция была по всему вашему коду...