let safeToProceed = false;
function isItSafe()
if (safeToProceed) {
alert("You shall pass!");
} else {
alert("You shall not pass!");
}
}
isItSafe();
Второй блок — это область инструкции if:
let safeToProceed = false;
function isItSafe() {
if (safeToProceed) {
alert("You shall pass!");
} else {
alert("You shall not pass!");
}
}
Третий блок — это область, охваченная инструкцией else:
let safeToProceed = false;
function isItSafe() {
if (safeToProceed) {
alert("You shall pass!");
} else {
alert("You shall not pass!");
}
}
Любая переменная, объявленная внутри блока через let или const, является локальной для этого блока и всех содержащихся в нем дочерних блоков. Чтобы лучше это понять, посмотрите на следующий код — вариацию функции isItSafe:
function isThePriceRight(cost) {
let total = cost + 1;
if (total > 3) {
alert(total);
} else {
alert("Not enough!");
}
}
isThePriceRight(4);
Мы объявляем переменную total как часть блока функции, затем обращаемся к ней внутри блока if. Как вы думаете, к чему это приведет? Переменная total полностью (ха-ха!) доступна отсюда, так как блок if является дочерним блоком блока функции. Выражаясь корректно, скажем, что переменная total находится в области функции alert.
А что насчет следующей ситуации?
function isThePriceRight(cost) {
let total = cost + 1;
if (total > 3) {
let warning = true;
alert(total);
} else {
alert("Not enough!");
}
alert(warning);
}
isThePriceRight(4);
У нас есть переменная warning, объявленная внутри блока if, а еще — функция alert, которая пытается вывести значение warning. В этом случае, так как мы пытаемся обратиться к переменной warning в блоке, находящемся вне блока, в котором она была объявлена, функция alert не будет отображать значение true. Учитывая то, где находится функция alert, переменная warning находится вне области видимости.
объявление переменных с ключевым словом var
Несколько абзацев выше я упомянул вскользь, что переменные когда-то объявлялись с помощью ключевого слова var. Ключевые слова let (и const) были введены позднее для облегчения объявления переменных. Если вы до сих пор используете var, пора переходить на let. Мы еще не обсуждали, почему let — более предпочтительный вариант, и решили, что обсудим это позже, когда начнем рассматривать области переменных подробнее. Что ж, настал этот момент!
Переменные, объявленные с var, распространяются на область функции. Они не распространяются на блоки, подобные инструкциям if и else. Если мы изменим последний пример, объявив в нем переменную warning с var вместо let, то код будет выглядеть так:
function isThePriceRight(cost) {
let total = cost + 1;
if (total > 3) {
var warning = true;
alert(total);
} else {
alert("Not enough!");
}
alert(warning);
}
isThePriceRight(4);
В изначальном варианте этого кода функция alert в отношении переменной warning ничего бы не отобразила, так как эта переменная, будучи объявленной с let, оказывалась вне области видимости. При использовании же var ситуация меняется и вы увидите отображение true. В этом и есть отличие между var и let. Область видимости переменных, объявленных с var, ограничивается уровнем функций, поэтому если переменная объявляется в любом месте внутри функции, то считается, что она находится в области видимости. Область же видимости переменных, объявленных с let, как мы увидели ранее, определяется уровнем блока.
Степень свободы, с которой переменная var определяет область видимости, слишком большая, и поэтому легко допустить ошибку, связанную с переменными. По этой причине я ратую за использование let, когда дело доходит до объявления переменных.
Как JavaScript обрабатывает переменные
Если вам показалось, что логика областей блока из предыдущего раздела выглядит странно, значит, вы еще не видели следующий пример. Взгляните на этот код:
let foo = "Hello!";
alert(foo);
Глядя на него, мы можем обоснованно утверждать, что отобразится значение Hello! и в целом будем правы. А что, если переместить объявление и инициализацию переменной в конец?
alert(foo);
let foo = "Hello!";
В этом случае код выдаст ошибку. Доступ к переменной foo осуществляется без обращения к ней. А теперь давайте заменим let на var, получив следующее:
alert(foo);