1. 先有鸡还是先有蛋
a = 2
var a
console.log(a) // 2
用 var 声明的变量会提升到作用域顶部
console.log(a) //undefined
var a = 2
那么到底是声明(蛋)在前还是赋值(鸡)在前?
2. 编译器
2.1 引擎在解释JavaScript 代码之前会先对其解释
变量和函数在内的所有声明都会在任何代码被执行前首先被处理
所以第一个代码片段会进行如下处理
var a
a = 2
console.log(a) // 2
第二部分的代码实际执行
var a
console.log(a) //undefined
a = 2
先有蛋 ( 声明 ) , 后有鸡 ( 赋值 ), 只有声明本身会被提升, 而其赋值或其他逻辑会留在原地 .
2.2 函数提升
foo()
function foo(){
console.log(a) //undefined
var a =2;
}
函数也同样会被提升,但是函数表达式不会被提升
foo() // Uncaught TypeError: foo is not a function
var foo = function(){
//...
}
3. 函数优先
函数声明和变量声明都会被提升,但是函数会首先被提升,然后才是变量.
foo() // 1
var foo
function foo(){
conosle.log(1)
}
foo =function(){
console.log(2)
}
由于函数提升先于变量,所以代码被引擎理解为如下形式
function foo(){
console.log(1)
}
foo() // 1
foo = function(){
console.log(2)
}
尽管 var foo 出现在 function foo(){} 之前,但是它是重复的声明(被忽略了),
因此函数声明会被提升到普通变量之前.
4. 小结
-
函数和变量都会提升,但是其赋值不会随之提升.
-
函数提升会优先于变量提升(重复声明会被忽略)