Одной из наиболее важных функций в JavaScript является использование закрытия. Из -за использования закрытия текущая область всегда может получить доступ к внешним областям. Поскольку JavaScript не имеет объема на уровне блока и только с помощью функций, использование закрытия тесно связано с функциями.
Имитировать личные переменные
Кода -копия выглядит следующим образом:
счетчик функций (Start) {
var count = start;
возвращаться {
Приращение: function () {
count ++;
},
get: function () {
возврат подсчет;
}
}
}
var foo = счетчик (4);
foo.increment ();
foo.get (); // 5
Здесь счетчик возвращает два закрытия: увеличение функции и получить. Эти две функции сохраняют доступ к масштабам счетчика, поэтому они могут получить доступ к количеству переменных, определенной в области подсчета.
Рабочий механизм частных переменных
Поскольку JavaScript не может присвоить значения и ссылки на области применения, в приведенном выше примере нет способа напрямую добраться до внутреннего подсчета переменных переменных извне. Единственный способ - получить к нему доступ, определив закрытие.
Кода -копия выглядит следующим образом:
var foo = новый счетчик (4);
foo.hack = function () {
счет = 1337;
};
Приведенный выше код не изменяет значение переменной счета в рамках счетчика счетчика, потому что HACK не определяется в счетчике. Приведенный выше код будет только создавать или перезаписать количество глобальных переменных.
Закрытие в петле
Одна из самых простых ошибок - использовать закрытие в петле.
Кода -копия выглядит следующим образом:
для (var i = 0; i <10; i ++) {
settimeout (function () {
console.log (i);
}, 1000);
}
Приведенный выше код не выведет от 0 до 9, но непрерывно выводит 10 раз.
Приведенная выше анонимность сохранит ссылку на переменную i. Когда функция Console.Log вызвана для запуска вывода, это контур, который закончился, и переменная I уже 10.
Чтобы избежать приведенной выше ошибки, нам нужно создать копию переменной, которую я значу каждый раз, когда мы зацикливаемся.
Избегайте ошибок
Чтобы скопировать значение переменной в цикле, лучший способ - добавить анонимную функцию во внешний слой и немедленно выполнить ее.
Кода -копия выглядит следующим образом:
для (var i = 0; i <10; i ++) {
(функция (e) {
settimeout (function () {
console.log (e);
}, 1000);
})(я);
}
Эта внешняя анонимная функция принимает переменную цикла I в качестве первого параметра и копирует свое значение своему собственному параметру e.
Внешняя анонимная функция передает параметр e в установку, поэтому SetTimeout имеет ссылку на параметр e. Более того, значение этого параметра E не будет изменяться из -за изменений внешнего цикла.
Есть еще один способ достичь того же эффекта, который состоит в том, чтобы вернуть анонимную функцию в анонимной функции в Settimeout:
Кода -копия выглядит следующим образом:
для (var i = 0; i <10; i ++) {
settimeout ((function (e) {
return function () {
console.log (e);
}
}) (i), 1000)
}
Кроме того, это также может быть достигнуто с помощью метода привязки.
Кода -копия выглядит следующим образом:
для (var i = 0; i <10; i ++) {
setTimeout (console.log.bind (консоль, i), 1000);
}
В конце статьи давайте обобжим:
(1) Закрытие является принципом дизайна. Он упрощает пользовательские вызовы, анализируя контекст, позволяя пользователю достичь своей цели, не зная об этом;
(2) Основные онлайн -статьи об анализе закрытия на самом деле противоречат принципу закрытия. Если вам нужно знать детали закрытия, который будет хорошо использоваться, это закрытие является сбоем дизайна;
(3) Попробуйте учиться как можно меньше.