Javascript 吊装示例需要解释

Explanation Needed For A Javascript Hoisting Example

我正在研究一些 Javascript 提升概念并遇到了这个例子。

console.log(a)
var a=5;

function a(){
console.log('In Console')
}

console.log(a)

输出是

function a() {
 console.log('In Console');
} 

5

我不明白两个 console.logs

的不同行为

谁能解释一下?

谢谢!

函数声明随其主体一起提升(按规范)。因此,function a 在第一个 log 之前吊装。然后,变量 a 被重新赋值,第二个 log 打印 5.

所以,提升后你的函数变成这样:

var a;

a = function(){
    console.log('In Console')
}

console.log(a)
a=5;
console.log(a)
// at this point a is a function, variable below has not yet been assigned. 
// functions can be called from anywhere in the code file (not taking scope into account)
console.log(a)
// a is now assigned to a variable and assigned to 5, it no longer refers to the function
var a=5;

// function defined as a which can be called as a until a is reassigned
function a(){
console.log('In Console')
}

// a now refers to 5 at this point in the execution
console.log(a)

根据spec

  1. Let declaredFunctionNames be an empty List.

  2. Let declaredVarNames be an empty List.

还有

15.b.i Let bindingExists be varEnvRec.HasBinding(vn).

这意味着 JS 引擎将首先提升函数声明,并在遍历变量声明时检查变量名称是否已经具有绑定。

解释如下

// Before the following console statement function has been hoisted already and variable declaration is ignored.
console.log(a)

var a=5; // now the value of a is initialized.

//this statement has been hoisted above already
function a(){
console.log('In Console')
}

//value of a is 5 now
console.log(a)