如何在javascript中提升空函数声明?

时间:2016-10-27 11:13:30

标签: javascript hoisting

看一下这个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);

1 个答案:

答案 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);