我有示例代码:
var t = 20;
function test () {
console.log(t);
var t = 100;
}
test();
结果将为undefined
。我认为t
是全局变量,所以当我记录它时,为什么它是undefined
?
答案 0 :(得分:5)
变量的范围是您查看此内容的原因。来自MDN documentation on var
:
var hoisting
因为在执行任何代码之前处理变量声明(以及一般的声明),所以在代码中的任何地方声明变量等同于在顶部声明它。这也意味着变量可以在声明之前使用。此行为称为" hoisting",因为看起来变量声明被移动到函数或全局代码的顶部。
JavaScript中的变量是功能范围,这意味着它们只存在于函数中。由于变量声明是在任何代码执行之前处理的,因此声明它们是封闭函数范围的开头。这"预处理"被称为" hoisting",因为声明被提升到封闭的函数范围的开头。由于您在函数内部重新声明t
,因此它在函数的开头声明(因为变量是函数范围的)并且等效于此:
var t = 20;
function test () {
var t;
console.log(t);
t = 100;
}
test();
由于t
在日志记录后分配给它之前从未给出值,因此undefined
var
。解决方案是删除foo(); //logs "foo called!"
function foo() {
console.log("foo called!");
}
重新声明。因此,在函数中没有看到变量的声明,也没有任何东西被悬挂。
请注意,此提升程序与您在定义之前使用函数声明的原因相同:
foo

函数声明(和仅声明)像变量一样被提升(但是整个声明被提升,而不仅仅是名称)。因此,在任何执行发生之前声明该函数,并且当代码运行时,userIds
被调用,因为它已经被声明。
答案 1 :(得分:1)
来自MDN:
因为在执行任何代码之前处理变量声明(和一般声明),所以在代码中的任何地方声明变量等同于在顶部声明它。这也意味着变量可以在声明之前使用。此行为称为“提升”,因为看起来变量声明被移动到函数或全局代码的顶部。
这意味着新函数t
变量的函数的声明在函数开头有效执行。这会立即使用本地变量模糊“全局”t
变量。但是,在您登录到控制台之后,才会执行将值设置为新t
变量的代码行。因此默认值为undefined
。
在这个例子中,也许不是JavaScript最直观的功能,我承认。但与此同时,它突出了代码清晰度的重要性。有两个同名的变量,即使尝试可以在同一范围内访问,也是错误的潜在来源。给他们不同的名字会更好。
答案 2 :(得分:0)
t
既是全球性的,也是本地性的。
当你进入一个函数时,有一个名为scope
的东西。这意味着您可以声明与全局变量具有相同名称的变量,它们实际上将完全不同。现在注意你放置console.log()
的位置。如果你没有对你的函数中的变量t
进行十分转换,那么你会记录20,但是你这样做了,函数关注的是函数&t。但是你在宣布t之前就开始记录了!
var t = 20;
function test () {
console.log(t);
}
test();

var t = 20;
function test () {
console.log(t);
var t = 100;
}
test();

您的代码等同于:( var在未定义的情况下移动到顶部。称为“吊装”。)
var t = 20;
function test () {
var t;
t = 100;
console.log(t);
}
test();