在ES6之前,JavaScript没有块级作用域(一对花括号{}即为一个块级作用域),只有全局作用域和函数作用域。变量提升即将变量声明提升到它所在作用域的最开始的部分
引擎会在解释 JavaScript 代码之前首先对其进行编译(没错,JavaScript
也是要进行编译的!),而编译阶段中的一部分工作就是找到所有声明,并用合适的作用域将他们关联起来,即
包括变量和函数在内的所有声明都会在任何代码被执行前首先被处理。
1.引擎在解析 JavaScript 代码之前首先对其进行编译。编译阶段中的一部分工作就是找到所有的声明,并用合适的作用域将它们关联起来;
2.变量和函数在内的所有声明都会在任何代码被执行前首先被处理;
3.当定义一个 var a = 1; 时,可能会认为这是一个声明。但 JavaScript 实际上会将其看成两个声明: var a; 和 a = 1; 。第一个定义声明是在编译阶段进行。第二个赋值声明会被留在原地等待执行阶段。
**
函数提升
**
解析器在解析时对函数声明与函数表达式有着不同的优先级,实际上编译阶段函数声明会先于变量被提升,并使其在执行任何代码之前可访问,函数表达式实际上是变量声明的一种,因此函数声明提升优于函数表达式
函数声明才存在函数提升
var num = 20;
function test(){
console.log(num); // 20
num = 10; //去掉了var 就变成定义了全局变量了
console.log(num); // 10
}
test();
console.log(num); // 10
外面的是全局的。里面的可以访问它,里面定义的在输出后面,且不能变量提升。所以,就输出外面的20了
函数声明和变量声明都会被提升。但是函数会首先被提升,然后才是变量。
局部变量 变量声明提升
var a= 20;
function numa(){
console.log(a); // undefined
var a= 10; //局部变量
console.log(a); // 10
}
numa();
由于函数体内存在变量声明提升,所以上面代码实际运行如下:
var a = 20;
function numa(){
var a;
console.log(a); // undefined
a = 10;
console.log(a); // 10
}
numa();