为什么以下代码会打印undefined
?删除if
块后,它还会输出hello there
作为输出。
var message = "hello there!";
function hello(){
console.log(message);
if (true) {
var message = "wassup?!";
}
}
hello();
答案 0 :(得分:2)
它被称为吊装。来自the Mozilla docs(强调补充):
在执行任何代码之前,处理变量声明无论发生在何处。使用
var
声明的变量的范围是其当前的执行上下文,它是封闭函数,或者对于在任何函数外部声明的变量,是全局的。
var message
块中声明的if
会隐藏函数内所有代码的全局message
变量,包括对console.log()
的调用。
另外两点。首先,JavaScript将变量声明与变量初始化分开。这就是为什么本地message
变量在console.log(message)
执行时具有未定义的值,而不是"wassup?!"
。其次,因为提升是一种反直觉的行为(至少对于习惯于其他语言的程序员而言),大多数JavaScript linting工具会警告你关于var
语句不在其执行上下文的开头。我强烈建议您找到一个linting工具(JSLint,JSHint,ESLint和JSCS)并使用它。
答案 1 :(得分:1)
当您定义一个与全局同名的局部变量时,会发生这种情况。由于函数范围内有var message
,因此它仅引用本地message
而不是全局undefined
。由于当时没有给出值if
。请注意,如果您将其移至"wassup?!"
后var message = "wassup?!"
。
解决方案是你不太想要制作一个局部变量。因此,将message = "wassup?!"
更改为{{1}}。
答案 2 :(得分:1)
为了添加@Spencer Wieczorek的回答,变量定义是“#sti; hoisted'在其范围的顶部,变量赋值保留在您编写它的位置。因此,您提供的代码实际上是这样翻译的:
var message = "hello there!";
function hello(){
var message;
console.log(message);
if (true) {
message = "wassup?!";
}
}
hello();
这更清楚地解释了为什么您会看到这些结果 - 在console.log()
调用之前,message
变量是在hello()
函数的范围内创建的,但它没有&#39 ; t得到值'wassup?!'
,直到函数的后面。
编辑:Here's a bit more info on this behaviour,正如@TedHopps在评论中指出的那样,被称为悬挂式,而不是'搭便车。