请考虑以下代码:
var a = 'a';
function b() {
console.log(a);
if (!a) {
var a = 'b';
}
}
b();
运行b()
将undefined
打印到控制台。但是,如果您删除if
语句,或者只是从var
语句中的表达式中删除if
关键字,以便重新定义外部a
变量,字符串a
将按预期打印到控制台。
任何人都能解释一下吗?我能想到的唯一原因是这是竞争条件,而if
语句的运行速度比console.log
快一点。
答案 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)
在函数中使用var
语句时,它将创建一个新函数,该函数是该函数的本地变量。
函数中声明的所有变量都将移动到函数的顶部,而不管它们实际声明的位置。这称为吊装。
默认情况下,提升的变量的值为undefined
,直到明确指定值为止。
由于第3点,它按原样打印undefined
。
在您的情况下,您在a
块中声明了变量if
。由于变量已被提升,因此声明将移至函数的顶部。它与外部变量的名称相同。当您在函数中访问a
时,如果存在该名称的变量,它将首先查看当前范围。仅当在本地范围内找不到其他范围时,它才会检查其他范围。因此,本地a
会影响外部a
。删除var语句时,本地范围内没有a
,因此使用外部a
。这就是它打印a
。