#javascript
#javascript
Вопрос:
var age = 23;
function foo() {
console.log(age);
var age = 65;
console.log(age);
}
foo();
Выводит:
undefined
65
но
var a = 'hello!';
first();
function first() {
var b = 'hi!';
second();
function second() {
var c = 'hey!';
console.log(a b c);
}
}
Выводит:
hello!hi!hey!
Почему в первой функции age
не определено, а во второй a
правильно привязано к hello!
?
Комментарии:
1. когда вы используете var в новой области видимости, это создает совершенно новую переменную. если вы хотите переопределить существующую переменную, вам нужно оставить
var
вне ее
Ответ №1:
Потому что, когда вы используете var и пишете это:
function foo() {
console.log(age);
var age = 65;
console.log(age);
}
js думает, что вы написали это:
function foo() {
var age; // it is undefined
console.log(age);
age = 65;
console.log(age);
}
Когда вы объявляете переменные с помощью var
, объявление локальной переменной фактически происходит в верхней части функции, и это скрывает переменную от глобальной области видимости.
Также, как упоминалось в комментарии, вам действительно следует использовать let
or const
и забыть о var
. var
на данный момент устарел, imo.
Комментарии:
1. Правильно, также полезно указать, что такого поведения можно избежать, используя let вместо var для функциональных переменных
2. Она ведет себя по-разному из-за области видимости, вторая функция вложена внутрь первой, поэтому у нее будет доступ к переменной b , когда она регистрируется на консоли
Ответ №2:
В Javascript переменные «подняты», то есть даже те, которые вы поместили age
во вторую строку в foo
, на самом деле код выглядит следующим образом:
function foo() {
var age; // which in practice means that age = undefined
console.log(age);
age = 65;
console.log(age);
}
Ответ №3:
это из-за подъема — широко известной проблемы с переменными, созданными с помощью ключевого слова var. Каждый раз, когда вы объявляете таким образом, ваша переменная всплывает до начала функции, независимо от того, где именно вы ее объявляете. Вот почему
function foo() {
console.log(age);
var age = 65;
console.log(age);
}
похоже на
var age = 23;
function foo() {
var age // age hoisted to here
console.log(age);
age = 65;
console.log(age);
}
Это также создает проблемы с циклами и асинхронными операциями, как показано ниже:
function foo() {
for (var i = 0; i <= 6; i ) {
setTimeout(()=>console.log(i), 0)
}
}
foo()
Вместо ожидаемого результата, подобного 0,1,2 .., вы получите семь из 7, и причина та же — объявление var, поднимающееся до вершины функции, нарушает область видимости цикла. Затем цикл завершает свою работу, i становится 7, и это значение попадает в обратный вызов setTimeout благодаря закрытию.
Чтобы избежать этого, вообще не используйте var — поскольку в ES6 как const, так и let являются наилучшей практикой.