Закрытия создаются в время определения функции . Итак, если у вас есть:
var a = 1;
function foo() {
console.log(a);
}
Это закрытие. Он «закрывает» внешние переменные. В этом случае a
. Честно говоря, «закрытие» никогда не имело для меня смысла (вероятно, с другой точки зрения), поэтому я предпочитаю думать об этом таким образом - функция, которая имеет доступ к внешней области видимости. В этом случае a
происходит из внешней области видимости.
Это может показаться немного странным, потому что во многих примерах и объяснениях замыканий есть что-то вроде:
function outer() {
var a = 1;
return function inner(b) {//<-----------
return a + b; // |
} // |
} // |
// |
var add1 = outer(); // |
// |
console.log(add1.name); // "inner" ---
console.log(typeof a); // undefined
console.log(add1(41)); // 42
Где объяснение состоит в том, что inner
является закрытием. создается , как только выполняется outer
(время определения для inner
), а затем возвращается из outer
. Специальным свойством замыкания является то, что он сохраняет ссылку на переменную a
, которая в настоящее время находится вне области видимости. Это true , но это производит неправильное впечатление. Там не должно быть внешней ссылки в функции, чтобы она была замыканием. Даже чистая функция , такая как:
function add(a, b) {
return a + b;
}
, которая не использует внешние ссылки и является полностью автономной, создает замыкание при создании.
Короче говоря, любая Функция в JavaScript является замыканием и никогда не была.
Однако это немного более академично c. Как уже упоминалось, полезным свойством замыканий является то, что они сохраняют ссылки на область, в которой они определены. Поэтому на практике мы обычно ссылаемся на замыкания только при использовании этого свойства - так, в примере с inner
и outer
- оба сформировали замыкания, но мы сосредоточимся на inner
, потому что на самом деле он использует внешнюю область видимости.