В JavaScript следует объявлять переменные посредством ключевого слова
var перед тем, как использовать их:var x; // Пока содержит значение undefined. console.log(y); // Возбуждает исключение: ReferenceError: y is not defined
Можно объявить несколько переменных единой инструкцией
var:
varx=1,y=2,z=3;
Однако я рекомендую использовать по одной инструкции для каждой переменной (причина объясняется в разделе Синтаксис). Таким образом, следует переписать этот код так:
varx=1;vary=2;varz=3;
В соответствии с принципом "возвышения" (см. "Возвышенные" переменные), лучше всего объявлять переменные в начале программы.Переменные видны функциям
functionfoo(){varx=-512;if(x<0){// (1)vartmp=-x;...}console.log(tmp);// 512}
Здесь видно, что переменная tmp не ограничена своим блоком, начинающимся со строки (1). Она существует до окончания функции."Возвышенные" переменные
functionfoo(){console.log(tmp);// undefinedif(false){vartmp=3;// (1)}}
Внутри JavaScript-интерпретатора предыдущая функция преобразуется к такому виду:
functionfoo(){vartmp;// hoisted declarationconsole.log(tmp);if(false){tmp=3;// assignment stays put}}
Замыкания
functioncreateIncrementor(start){returnfunction(){// (1)start++;returnstart;}}
Функция, начинающаяся на строке (1) покидает контекст, в котором была создана, но остается связанной с переменной start:var inc = createIncrementor(5); inc() // Вернет 6. inc() // Вернет 7. inc() // Вернет 8.Замыкание - это функция в совокупности с переменными, находящимися в ее области видимости. Таким образом, функция
createIncrementor() возвращает как раз то, что называется замыканием.Паттерн IIFE: внедрение новой области видимости
(function(){// open IIFEvartmp=...;// not a global variable}());// close IIFE
Убедитесь, что используете этот пример в точности так, как он здесь приведен (за исключением комментариев). IIFE вызывается сразу же после своей декларации. Внутри функции находится новая область видимости, предохраняющая переменную
tmp от попадания в глобальное пространство. Подробнее см. Введение новой области видимости посредством IIFE.Способы использования IIFE: беззаботное использование замыканий
varresult=[];for(vari=0;i<5;i++){result.push(function(){returni});// (1)}console.log(result[1]());// 5 (not 1)console.log(result[3]());// 5 (not 3)
Значение, возвращаемое в строке (1), всегда указывает на текущее значение переменной i, а не на то значение, которое оно имело в момент создания внутренней функции. По окончании цикла i приобрело значение 5. Вот почему все функции в массиве возвращают одно и то же значение. Если вы хотите, чтобы функция в строке (1) возвращала текущее состояние i, вы можете прибегнуть к IIFE:
for(vari=0;i<5;i++){(function(){vari2=i;// copy current iresult.push(function(){returni2});}());}
Этого результата можно достичь и проще, но пример дан для иллюстрации использования паттерна.
Комментариев нет:
Отправить комментарий