看一下这个site中的提升示例,我不明白为什么即使在吊装之后,下面的内容也会改变:
var a = 1;
function b() {
a = 10;
return;
function a() {}
}
b();
alert(a); // alerts 1
实际上是
var a = 1;
function b() {
function a() {}
a = 10;
return;
}
b();
alert(a);
不应该改变10,因为在a
函数返回之前b
仍然被分配给10?为什么调用一个空函数导致这个?在相关的说明中,为什么下面没有警报功能但仍然改变1?是否a
被重新分配给声明的函数?
var a = 1;
function a() {}
alert(a);
答案 0 :(得分:4)
让我们一行一行,
在这里,您b();
调用函数b
。身体中有b
函数是什么?声明名为a
的新函数。当您在a
内访问b
时,实际上您不会访问全局变量a
,而是访问您刚刚声明的函数。因此,10将被设置为指向称为a的函数的指针,而不是名为
但为什么第一个代码块会警告1?我很困惑
因为当JavaScript引擎执行赋值时:
a = 10;
检查已定义a
的位置。因为在当前范围中,您尝试将10设置为a
,所以有一个函数声明,其名称为a
,然后将发生我上面描述的情况。但你会说为什么?函数声明在赋值之下。发生这种情况的原因是JavaScript引擎首先处理脚本中的声明,然后继续执行脚本。因此,当引擎询问a
时,a
定义在哪里,一如既往地首先查看当前范围。如果没有那么它将查看当前范围所包含的范围。在您的情况下,这是全局范围,我可以从您的代码中推断出来。所以如果你没有定义这个函数,我之前提到的第二步就已经完成了,因为有一个名为a
的变量,它会改变它的值。如果没有任何变量,那么就会在全局范围内定义a
,它的值将为10。
var a = 1;
function b() {
a = 10;
return;
// I renamed the function from a to c to notice the hoisting
function c() {}
}
b();
console.log(a);