变量提升

146 阅读1分钟

通过阅读《你不知道的javascript》的第四章提升所做的笔记。

1. 先有蛋(声明)后有鸡(赋值)

a = 2 
var a
console.log(a)
输出什么?

答案是输出2,因为var声明变量,存在变量提升。变量提升到底是什么呢?

程序的执行并不是我们所看到的从上而下,编译分为两个阶段,定义声明(var a)是在编译阶段进行的,赋值声明(a = 2)则会被留在等待执行阶段

编译器中真正的代码执行顺序应该是这样的:
var a
a = 2 
console.log(a)

2. 只有声明本身会被提升,其他运行逻辑会被留在本地

console.log(a)
var a = 2
输出什么呢?undefined

与上同理,编译器中真正的代码执行顺序应该是这样的:
var a
console.log(a)
a = 2

3. 只有函数声明会被提升,函数表达式不会被提升

foo() // 结果为TypeError,而不是ReferenceError
var foo = function bar() {
    // ....
}

4. 函数变量声明会被提升到普通变量之前

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

foo = function foo() {
    console.log(2)
}

是输出1还是2呢?

首先function foo() 函数的变量提升到最上面,忽略掉了var的重复变量声明,编译器中真正的代码执行顺序应该是这样的:

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

foo()

foo = function foo() {
    console.log(2)
}

总结:

作用域中的声明不论出现在什么地方,都会被编译器优先处理。
可以将这个过程形象地想象成所有的声明(变量和函数)都会被“移动”到各自作用域的最顶端,这个过程被称为提升。