Понятие замыкания тесно связан с пониманием области видимости. Еще раз отмечу тот факт, что JavaScript не поддерживает области видимости блока, только функции определяют область видимости. Если я внутри функции определю внутреннюю функцию, то это внутренняя функция будет иметь доступ к параметрам и переменным той функции в которой она определена - это свойство называют замыканием. Замыкания - это сильная сторона JavaScript.
Работая с замыканиями надо быть аккуратным - иначе результат может не оправдать ваших ожиданий. Рассмотрим такой пример: есть отряд курсантов и мы произвели расчет по порядку. То есть первый курсант - "первый", второй - "второй" и т.д. Теперь мы хотим обратиться к курсанту и узнать его порядковый номер.
Создадим функцию stroy().
Теперь мы хотим обратиться к курсанту и он должен сказать свой порядковый номер, что ж попробуем.
Мы рассчитываем увидеть "третий", но увы получаем
Работая с замыканиями надо быть аккуратным - иначе результат может не оправдать ваших ожиданий. Рассмотрим такой пример: есть отряд курсантов и мы произвели расчет по порядку. То есть первый курсант - "первый", второй - "второй" и т.д. Теперь мы хотим обратиться к курсанту и узнать его порядковый номер.
Создадим функцию stroy().
function stroy() {
var poryadok = ["первый", "второй", "третий"],
i,
kursants = [];
for (i = 0; i < 3; i++) {
kursants[i] = function () {
return poryadok[i];
};
}
return kursants;
}
Теперь мы хотим обратиться к курсанту и он должен сказать свой порядковый номер, что ж попробуем.
var otryad = stroy(); console.log(otryad[2]());
Мы рассчитываем увидеть "третий", но увы получаем
Хм, не совсем то, что мы ожидали. Давайте разберемся в чем дело и исправим нашу программу. Самый первый вопрос, который приходит в голову, а какое значение имеет переменная i, когда мы возвращаем poryadok[i]. Для отладки закоментируем строкуundefined
//return poryadok[]и напишем
console.log(i)Теперь видим, что в момент вызова poryadok[i] переменная i равна 3. Получается мы вышли за предел массива и получили вполне заслуженно undefined. Особенность заключается в том, что внутренняя функция при замыкании получает значение переменной внешней функции по ссылке. Получается, что после окончания цикла, переменная i будет иметь значение 3, которое по ссылке и получит внутренняя функция. Есть способ обойти эту особенность и получить нужное поведение. Для этого будем использовать немедленно вызываемую функцию.
function stroy() {
var poryadok = ["первый", "второй", "третий"],
i,
kursants = [];
for (i = 0; i < 3; i++) {
kursants[i] = (function (num) {
return function () {
return poryadok[num];
}
})(i);
}
return kursants;
}
var otryad = stroy();
console.log(otryad[2]());
Запустим на исполнение и увидим в результатеВот теперь другое дело. Что ж на этом все. Далее поговорим о прототипах и наследовании."третий"











