Статьи

Совет по производительности JavaScript с использованием Closure

Вот простой совет по производительности JavaScript с использованием замыкания JavaScript, который так быстро объяснить, что у вас нет причин не продолжать чтение. Подумайте об этом: вам нужна функция, которая сообщит вам позицию в команде по регби на определенное число. Те из нас, кто знаком со спортом, знают, что в регби разные позиции всегда имеют одинаковое количество.

  1. Свободная голова
  2. проститутка
  3. Тугая голова
  4. Замок
  5. Замок
  6. Фланкер (слепая сторона)
  7. Фланкер (открытая сторона)
  8. № 8
  9. Скрам половина
  10. Из половины
  11. Левое крыло
  12. Внутри Центр
  13. Центр
  14. Правое крыло
  15. Полный назад

Итак, для вашей первой попытки вы определяете массив позиций в глобальном пространстве имен, а затем функцию для разрешения позиции для данного числа.

var positions = ['No position', 'Loose head', 'Hooker', 'Tight head', 'Lock', 'Lock', 'Flanker', 'Flanker', 'No. 8',  'Scrum half', 'Out half', 'Left wing', 'Inside centre', 'Outside centre', 'Full back']
 
var getPosition = function(n) {
   return positions(n);
}

Все начинают смеяться над вами во время проверки кода. Вы получаете комментарии, такие как:

«Не загрязняйте пространство имен, перепишите, пожалуйста».

«Вы даже не удосужились использовать JsLint?»

«Вы хотите картофель фри с этим?»

Для второй попытки вы помещаете массив позиций в функцию в качестве локальной переменной.

var getPosition = function() {
    var positions = ['No position', 'Loose head', 'Hooker', 'Tight head', 'Lock', 'Lock', 'Flanker', 'No. 8', 'Flanker', 'Scrum half', 'Out half', 'Left wing', 'Inside centre', 'Outside centre', 'Right wing' 'Full back'];   // positions is a local variable
   return positions[n];
}

Вернемся ко второму обзору кода:

«Ну, это лучше, но вы понимаете, что каждый раз, когда вызывается эта функция, массив выделяется?»

«Но вы сказали, не загрязняйте глобальное пространство имен»

«Посмотрите, у нас здесь есть стандарты, не загрязняйте глобальное пространство имен и не несите затрат на производительность, когда вам не нужно это делать»

«Хорошо»

Вы оставляете код обзор унылый и удрученный. Вернувшись к своему кофейному столу, когда ваши наушники на малой громкости, вы все время слышите слово «закрытие, закрытие, закрытие» от нескольких ботаников JavaScript, сидящих рядом с вами. В тот вечер тебе трудно заснуть. 
Закрытие, закрытие, закрытие . Слово не покинет твою голову. 
Закрытие, закрытие,закрытие, Да, вы знаете, что замыкания предлагают способ инкапсуляции кода в JavaScript, но дело не в инкапсуляции. Подожди секунду! Замыкания закрывают свободные переменные и делают их доступными для лексической области видимости. Хммм … Это значит, что ты мог бы сделать что-то вроде …

var getPosition = function () {
    var positions = ['No position', 'Loose head', 'Hooker', 'Tight head', 'Lock', 'Lock', 'Flanker', 'Flanker', 'No. 8', 'Scrum half', 'Out half', 'Left wing', 'Inside centre', 'Outside centre', 'Right wing' 'Full back'];   // positions is a local variable
    return function(n) {
        return positions[n];
    }
}()
 
console.log(getPosition(4));

Что тут происходит?

  • Внутренняя функция «закрывает» массив позиций
  • Внешняя функция возвращает внутреннюю функцию, которая затем присваивается ей переменной getPosition
  • Внешняя функция вызывает себя. Это означает, что объявление, вызов и присваивание будут происходить одновременно.
  • Поскольку это внешняя функция, которая распределила массив, и поскольку внешняя функция вызывается только один раз, массив выделяется только один раз.
  • Поскольку внутренняя функция имеет доступ к тому, что она «закрывает» даже после выполнения внешней функции, это означает, что внутренняя функция будет иметь доступ к массиву позиций (который выделяется только один раз).

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

«В третий раз повезло».

Вы можете подумать, что размещение массива в JavaScript занимает не так много времени, разве это не перебор? Смотря как. Ваше приложение нуждается в сжатии каждую нано секунду? Является ли объем данных, который вам нужен для инициализации, более 15 элементов в массиве? Это уместные вопросы, конечно. Но эту технику удобно знать, потому что инкапсуляция — это не единственное преимущество замыканий.