Ответ 1
Цитирование MDN Docs на var
hoisting,
Поскольку объявления переменных (и декларации вообще) обрабатываются до того, как выполняется какой-либо код, объявление переменной в любом месте кода эквивалентно объявлению ее вверху. Это также означает, что переменная может как представляется, используются до его объявления. Это поведение называется "подъем", поскольку, как представляется, объявление переменной перемещается в начало функции или глобального кода.
Итак, в вашем случае JavaScript знает, что локальная переменная (а не заявленная за пределами) x
определена где-то в функции, но она не знает ее фактического значения до тех пор, пока выполнение не достигнет инструкции присваивания, присваивает x
. (Заявления обрабатываются во время компиляции, и настройки выполняются во время выполнения). Пока не будет выполнено назначение, будет использоваться значение по умолчанию undefined
. Поскольку undefined
является ложным, условие
if (!x) {
выполняется и выполняется оператор присваивания. Вот почему вы получаете hoisted
в поле предупреждения.
Скажем, вы не объявили x
внутри функции,
var x;
var y = function () {
if (!x) {
x = 'hoisted';
}
alert(x);
}
y();
alert(x);
Здесь, поскольку x
не объявляется нигде внутри функции, во время выполнения JavaScript будет искать x
в более высоких областях. В этом случае он находит это прямо вне функции. Таким образом, будет использоваться x
. Поскольку вы назначили hoisted
на x
, внутренний alert
также скажет hoisted
и после выхода из функции alert(x)
также будет предупреждать hoisted
.