无法理解此javascript代码的输出

时间:2015-12-17 05:04:07

标签: javascript

为什么以下代码会打印undefined?删除if块后,它还会输出hello there作为输出。

var message = "hello there!";

function hello(){
  console.log(message);

  if (true) {
    var message = "wassup?!";
  }
}

hello();

3 个答案:

答案 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在评论中指出的那样,被称为悬挂式,而不是'搭便车。