Что происходит, когда имя переменной 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