Это работает точно так, как и должно быть: объявления (, но не присвоенные значения ) для «возраста» и «рода занятий» подняты, поэтому в журнале консоли они отображаются со значением «undefined» ( вместо того, чтобы бросать ReferenceError
), но name
особенный: вы не тот, кто его объявил, даже если ваш код делает его похожим на вас:
Что на самом деле происходит то, что написанный вами код ограничен, и поэтому, когда вы говорите var name = "tom"
, на самом деле вы пишете currentscope.name = "tom"
. В любой явной области видимости (функция, модуль и т. Д. c) это будет вести себя так, как вы ожидали, но в глобальной области видимости в браузере (или, точнее, «в любом контексте выполнения в ваша область действия window
"), это означает, что ваш код фактически выполняется как window.name = "tom"
.
И вот в чем дело go неправильно: name
уже существует как глобальное свойство для window
объекта
Конечно, это касается любого другое значение, если вы var numbats = "cute";
в глобальной области видимости, это то же самое, что и window.numbats = "cute";
, поэтому, если вы не хотите сталкиваться с конфликтами именования без вывода сообщений: не объявляйте вещи в глобальной области видимости Проверьте это в функции (где var name
будет shadow global name
), или вы можете использовать современный JS и использовать let
вместо блока фигурных скобок, но, конечно, тогда мы больше не используем var
.
Забавный малоизвестный факт: установка глобального name
на "tom"
и последующий просмотр веб-страниц в течение часа на той же вкладке, даже через час, все равно window.name
будь твоей ценностью, если только кто-то другой не изменил ее, чего почти не бывает Это один из тех веселых способов, с помощью которых возможно многогранное отслеживание.