功能和可变提升的意外结果

BoS*_*YyY 9 javascript hoisting

我正在读"你不懂JS"系列的第二本书,我读过在变量之前函数被提升了.

所以这是代码:

foo(); // 1

var foo;

function foo() {
    console.log( 1 );
}

foo = function() {
    console.log( 2 );
};
Run Code Online (Sandbox Code Playgroud)

这个输出将是1.但为什么呢?首先提升函数,然后提升变量.因此,在我的函数foo(打印1的那个)被提升之后,它必须跟随变量foo.所以结果应该是"未定义"而不是"1".

我希望代码的行为就像它一样:

// hoisted first
function foo() {
    console.log( 1 );
}

// hoisted second
var foo;  // implicitly initialized to 'undefined'

foo();  // call 'undefined' - error?

foo = function() {
    console.log( 2 );
};
Run Code Online (Sandbox Code Playgroud)

这里发生了什么事?

Cer*_*nce 9

如上所述,函数在变量之前被提升; 如果interpterer 在范围内已经定义var foo 之后 遇到foo,它将被简单地忽略.它不分配fooundefined,它只是确保了命名变量foo在当前范围存在-它已经这样做了.

正如它在你不知道的JS链接中所说:

多次/重复var声明被有效忽略

这是另一个常见的被忽略的重复变量示例,可能更熟悉/更直观:

if (false)
  var foo = false;
else
  var foo = true;
Run Code Online (Sandbox Code Playgroud)

变成

var foo;
var foo; // does not actually do anything; does not assign `undefined` to `foo`, ignored
// foo just *happens* to not have anything assigned to it in almost all cases like this
if (false)
  foo = false;
else
  foo = true;
Run Code Online (Sandbox Code Playgroud)

  • @BoSsYyY,*赋值*没有被提升:它在您调用该函数后发生. (2认同)
  • @BoSsYyY函数声明被悬挂; 函数表达式(带`=`)不是.那*是*赋值,所以在赋值之前调用`foo`会得到`1`. (2认同)