Вы не можете объявить переменные условно.
Почему?
Процесс создания переменной происходит за до фактического выполнения кода, во время выполнения функции эти переменные уже будут связаны с локальной областью действия, например:
function foo () {
if (false) {
var test = 'foo'; // never executed
}
return test;
}
foo(); // undefined
Когда функция должна быть выполнена, идентификаторы формальных параметров, идентификаторы из объявлений переменных и идентификаторы из объявлений функций в теле функции привязываются к среде локальной переменной.
Переменные инициализируются с undefined
.
Кроме того, идентификаторы в локальной области видимости shadow остальные с тем же именем, расположенные выше в цепочке областей действия, например:
var test = 'global';
function bar () {
alert(test); // undefined, not "global", the local variable already declared
var test = 'xxx';
}
bar();
Если переменная test
нигде не была объявлена, будет выдано ReferenceError
:
function foo () {
return test;
}
try {
foo(); // ReferenceError!!
} catch (e) {
alert(e);
}
Это одна из причин того, почему, например, JSLint рекомендует только один var
оператор в верхней части функций, потому что, например, первый фрагмент действительно будет напоминать это при выполнении:
function foo () {
var test; // var statement was "hoisted"
if (false) {
test = 'foo'; // never executed
}
return test;
}
foo(); // undefined
Другая причина заключается в том, что блоки не вводят новую лексическую область видимости, это делают только функции, поэтому наличие в выражении оператора var
может заставить вас думать, что срок жизни переменной ограничен только этим блоком, но дело не в этом.
Объявления вложенных функций будут иметь аналогичное поведение подъем , они будут объявлены до выполнения кода, но они также инициализируются в этот момент:
function foo () {
return typeof bar;
// unreachable code:
function bar() {
//..
}
}
foo(); // "function"