Мне не хватает понимания того, что происходит с необъявленной переменной и где она заканчивается в документе. Например
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
console.log(a);
с подъемом станет
function b () {
function a() {}
a = 10;
return;
}
var a;
a = 1;
b();
console.log(a); // output 1
a = 10 назначается для функции внутри функции b. Это оставляет a = 1 для присваивания var a объявления. Теперь, если мы закомментируем функцию a, мы получим другой результат.
function b () {
// function a() {}
a = 10;
return;
}
var a;
a = 1;
b();
console.log(a); // output 10
Итак, теперь необъявленной переменной присваивается a = 10, поэтому она становится глобальной, так как именно это выглядит? Из-за изменяющейся мутации это будет помещено в конец документа, как это?
function b () {
// function a() {}
return;
}
var a;
a = 1;
b();
a = 10;
console.log(a); // output 10
Это правильно?
Этот тип вопросов и проблем уже был в Интернете в течение многих лет. но определенно у вас возникли проблемы с их поиском, поэтому я постараюсь объяснить вам (основываясь на моих знаниях, может быть, не на 100% правильно) немного подробнее для вас.
каждый объект живет внутри другого объекта (буквально каждый объект, даже само window
как глобальный объект; window.window.window
будет возвращать само window
, что немного запутанно, но не имеет значения.)
когда вы определяете переменную, вы должны рассмотреть объект для этой переменной, чтобы жить внутри. например, когда вы определяете
var a = 10;
в глобальном контексте это будет как
window.a = 10;
и я думаю, что до сих пор у вас уже есть идея. но мы продолжим. когда вы определяете необъявленную переменную внутри (или снаружи, не имеет значения) локального контекста (например, вашей function b() {}
), она будет принимать window
как родительский объект для этой переменной.
Итак, вот что происходит. вы уже объявили переменную с именем a
в вашем глобальном контексте. Теперь вы оцениваете это внутри вашей функции b()
.
function b() {
a = 99;
}
и если вы вызовете эту функцию b()
после вашего var a = 10
, a
будет 99
в конце дня.
как насчет этого объявления функции в вашем первом блоке кода (который стал комментарием в вашем втором блоке кода)?
это сделает локальную переменную с именем a
которая будет жить внутри этой функции в this
объекте (я знаю, this
вернет window
внутри этой функции, но это потому, что вы вызываете эту функцию в этом контексте. если вы вызываете свою функцию с метод как .call
он изменит контекст этой функции. так что функция this
является динамической ссылкой на объект контекста.), и если вы измените значение после этого, он будет оценивать, что a
a
качестве предварительно объявленной локальной переменной.
Я надеюсь, что это даст лучшее понимание того, что происходит.
b();
). Просто идентификаторa
теперь ссылается на другую (не локальную) переменную - так же, какconsole
ссылается на глобальную переменную, и все равно будет, если вы поместите вызовconsole.log()
внутри функции.