объявление var (например, var x;) перезапишет предыдущее значение - PullRequest
0 голосов
/ 16 января 2019

Я изучаю концепцию подъема в javascript. Один кусок кода, который заблокировал меня, это:

function foo() {
  console.log(8);
}

var foo;

console.log(foo);

Вопрос 1: Я набрал этот код в консоли Chrome, распечатать это

function foo(){
    console.log(8)
}

будет ли объявление переменной перезаписывать объявление функции? Я думаю, что распечатка должна быть undefined

Вопрос 2: Я набрал тот же код в онлайн-редакторе https://jsbin.com/dezixozewi/edit?js,console,, он выдает ошибку, поскольку 'Идентификатор' foo 'уже объявлен'. поэтому он вообще не допускает дублирования деклараций.

Может ли кто-нибудь помочь объяснить логику? Большое спасибо заранее!

Ответы [ 4 ]

0 голосов
/ 16 января 2019

переписывает ли объявление переменной объявление функции?

Нет. Перед выполнением любого кода среда выполнения находит все объявления функций и переменных и инициализирует с ними новую область видимости. Различия между оценкой кода скрипта и областью действия функции немного различаются, но результат один и тот же:

  • Повторяющиеся объявления игнорируются.
  • Объявление функции вычисляется в конце и присваивается соответствующему имени.

В глобальной области видимости, поскольку foo является как именем функции, так и объявлением переменной, объявление переменной игнорируется. А поскольку он не имеет инициализатора, значение foo не изменяется, когда эта строка фактически вычисляется.

Подробности можно найти в спецификации языка .


Вопрос 2: Я набрал тот же код в онлайн-редакторе https://jsbin.com/dezixozewi/edit?js,console, выдает ошибку, поскольку «Идентификатор« foo »уже объявлен». поэтому он вообще не допускает дублирования деклараций.

Непонятно, как jsbin оценивает код, но он действителен.

0 голосов
/ 16 января 2019

Причина, по которой функция является значением foo, заключается в том, что в этой строке:

var foo;

Вы просто заявляете foo - это утверждение, которое ничего не делает.

Если вы на самом деле установите foo на что-то, например "FooBar":

function foo() {
  console.log(8);
}

var foo = "FooBar";

console.log(foo);

Она перезаписывает функцию, потому что, как показано в в этом вопросе , объявление чего-либо со значением var, которое является значением, приведет к тому, что это значение будет "поднято" наверх и, таким образом, является фактическим значение идентификатора.

0 голосов
/ 16 января 2019

var foo; оператор объявляет foo переменную и устанавливает ее значение неопределенным , если оно уже не имеет значения . Ваш foo имеет значение, поскольку var foo; на самом деле ничего не делает.

Если вы удалите foo function и замените его простой переменной, вы увидите то же поведение.

0 голосов
/ 16 января 2019

var foo; просто указывает на ячейку памяти foo. Бывает, что вы уже объявили функцию там, поэтому значение foo по-прежнему остается функцией.

Это ничем не отличается от того, что вы сделали:

var x = 2;
var x; // We're not setting a value with `=`, so nothing gets overridden 
x; // 2
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...