在javascript代码执行之前,会进行预编译时期,在预编译期间会进行变量提升与函数提升。
什么是提升呢?
对于javascript引擎来讲,无论作用域中的声明在什么地方出现,都会在该作用域中被首先进行处理,就是所有变量与函数声明都会被移动到作用域的最顶端,这个过程就叫作提升。
为什么要进行提升?
1、提高性能
只需进行一次语法检查和预编译,就可以让每次执行函数时直接为函数中的变量分配栈空间,而不用每次都要扫描代码去获取声明了哪些变量与函数。(预编译过程会为函数生成预编译代码,会统计声明了哪些变量和函数,并对函数代码进行压缩)
2、容错性好
在开发的时候,我们有可能会将变量定义写在变量赋值的后面,因为有了变量提升,使得代码也可以正常运行。
下面来看看提升的例子。
变量提升
function test(){
console.log(a); //undefined
var a = 20;
console.log(a); //20
}
test()
等价于
function test(){
var a;
console.log(a); //undefined
a = 20;
console.log(a); //20
}
test()
函数提升
console.log(test1)
test1()
console.log(test2)
test2()
function test1() {
console.log("test1")
}
var test2 = function() {
console.log("test2")
}
等价于
var test1 = function() {
console.log("test1")
}
var test2;
console.log(test1)
test1() // test1
console.log(test2)
test2() // undefined
//函数表达式不会被提升
test2 = function() {
console.log("test2")
}
函数提升优先级大于变量提升优先级
console.log(test) // ƒ test() {}
function test() {}
var test = "test"
console.log(test) // test
关于let和const存不存在变量提升?
function test() {
debugger
console.log(a) //Cannot access 'a' before initialization
debugger
let a =1
debugger
console.log(a)
}
test()
运行结果:
我在网上找到回答是这样的:
let、const的声明都会存在变量提升,只不过这些变量所处于的状态被称为“temporal dead zone”,只有初始化的时候才能拿到变量的值。