为什么此控制台日志受后续if语句的影响?

时间:2014-12-14 03:35:29

标签: javascript

请考虑以下代码:

var a = 'a';

function b() {
    console.log(a);

    if (!a) {
        var a = 'b';
    }
}

b();

运行b()undefined打印到控制台。但是,如果您删除if语句,或者只是从var语句中的表达式中删除if关键字,以便重新定义外部a变量,字符串a将按预期打印到控制台。

任何人都能解释一下吗?我能想到的唯一原因是这是竞争条件,而if语句的运行速度比console.log快一点。

2 个答案:

答案 0 :(得分:1)

这不是竞争条件 - 它是一种语言功能,并且正在作为Javascript语言的设计者工作。

由于提升的变量定义(函数范围内的所有变量定义都被提升到函数的顶部),您的代码等同于:

var a = 'a';

function b() {
  var a;
  console.log(a);

  if (!a) {
    a = 'b';
  }
}

b();

因此,本地声明的a隐藏了全局声明的a,并且最初的值为undefined,直到您的if语句为其赋值。

您可以通过搜索"Javascript hoisting"找到有关Javascript语言此特征的大量讨论。

答案 1 :(得分:1)

  1. 在函数中使用var语句时,它将创建一个新函数,该函数是该函数的本地变量。

  2. 函数中声明的所有变量都将移动到函数的顶部,而不管它们实际声明的位置。这称为吊装

  3. 默认情况下,提升的变量的值为undefined,直到明确指定值为止。

  4. 由于第3点,它按原样打印undefined

    在您的情况下,您在a块中声明了变量if。由于变量已被提升,因此声明将移至函数的顶部。它与外部变量的名称相同。当您在函数中访问a时,如果存在该名称的变量,它将首先查看当前范围。仅当在本地范围内找不到其他范围时,它才会检查其他范围。因此,本地a会影响外部a。删除var语句时,本地范围内没有a,因此使用外部a。这就是它打印a

    的原因