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