通过阅读《你不知道的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)
}
总结:
作用域中的声明不论出现在什么地方,都会被编译器优先处理。
可以将这个过程形象地想象成所有的声明(变量和函数)都会被“移动”到各自作用域的最顶端,这个过程被称为提升。