Что происходит, когда имя переменной JavaScript и имя функции совпадают?

У меня есть следующий код, где я объявляю функцию, а после нее переменную с тем же именем, что и функция:

function a(x) {
    return x * 2;
}

var a;
alert(a);

Я ожидал, что это насторожит undefined, но если я запусту его, предупреждение будет отображать следующее:

функция а (х) {
возврат х * 2
}

Если я назначу значение переменной (например, var a = 4), предупреждение отобразит это значение (4), но без этого изменения a будет распознан как функция.

Почему это происходит?

6 ответов

Решение

Функции - это тип объекта, который является типом значения.

Значения могут храниться в переменных (и свойствах, и передаваться в качестве аргументов функциям и т. Д.).

Объявление функции:

  • Создает именованную функцию
  • Создает переменную в текущей области с тем же именем, что и функция (если такая переменная уже не существует)
  • Назначает функцию этой переменной
  • Поднимается

varзаявление:

  • Создает переменную в текущей области с указанным именем (если такая переменная уже не существует)
  • Поднимается
  • Не присваивает значение этой переменной (если не объединено с оператором присваивания)

Ваше заявление и var выписка поднята. Только один из них присваивает значение переменной a,

В JavaScript как объявление функции, так и объявление переменной отображаются в верхней части функции, если она определена в функции, или в верхней части глобального контекста, если она находится вне функции. И объявление функции имеет приоритет над объявлениями переменных (но не над назначением переменных).

Объявление функции переопределяет объявление переменной при подъеме

Сначала вы объявляете переменную:

var a; // value of a is undefined 

Во-вторых, значение a является функцией, потому что объявление функции имеет приоритет над объявлениями переменных (но не над назначением переменных):

function a(x) {
  return x * 2;
}

И это то, что вы получаете, когда звоните alert(a);,

Но если вместо объявления переменной вы назначаете переменную: var a = 4; чем присвоенное значение 4 будет преобладать.

Если вы используете имя функции в качестве имени переменной, ее значение заменяется телом функции. Таким образом, "var a" становится вашей функцией "a", и, следовательно, ваше предупреждение отображает функцию "a".

Вы также должны помнить, что var a поднят, что делает это больше так

var a; // placed

function a(x) {
  return x * 2;
};

var a; // removed
alert (a); // a is replaced by function body

Помни что var a поднят, так что если вы назначите 4 to a:

var a; // placed

function a(x) {
  return x * 2;
};

var a = 4; // removed
a = 4 // added

alert (a); // a is now 4

Происходит первый подъем. Объявление функции имеет приоритет над объявлением переменной во время подъема.

Во время выполнения кода, если в какой-либо точке присваивается переменная, то она заменяется, иначе остается та же функция.

( Примечание: сначала прочитайте код от строки 4 до строки 8. Затем снова прочитайте от начала до конца. )

      console.log(a); // f a(){...} - Executed just after hoisting
console.log(b); // f b(){...} - Executed just after hoisting

var a = 100; // here variable is assigned
function a(x) {...};

function b(x) {...};
var b; // only a declaration here

console.log(a); // 100
console.log(b); // f b(){...}

ES6 предлагает лучшее решение, определяя SyntaxError: Identifier (?) has already been declared когда используешь let / const вместо того var.

let

function foo () {}
let foo;
// => SyntaxError: Identifier 'foo' has already been declared

const

function foo () {}
const foo = 1;
// => SyntaxError: Identifier 'foo' has already been declared

Обратите внимание, что const foo;не работает. Это вызоветSyntaxError: Missing initializer in const declaration

Другие вопросы по тегам