JavaScript 代码是由浏览器中的 JavaScript 解析器来执行的,JavaScript 解析器在运行 JavaScript 代码时分为两步:预解析 和 代码解析。
预解析
1.1. 定义:js 引擎会把 js 里面所有的 var 和 function 提升到当前作用域的最前面
1.2. 代码执行:执照代码书写的顺序从下往下执行预解析分为:变量预解析(变量提升)和 函数预解析(函数提升)
2.1. 变量提升:就是把所有的变量声明,提升到当前的作用域最前面(注:不提升赋值操作)
2.2. 函数提升:就是把所有的函数声明,提升到当前作用域的最前面(注:不调用函数)预解析案例
// 案例1:结果是几?
var num = 10;
fun();
function fun(){
console.log(num); // 因为变量num被提前,所以num没有赋值,最终结果是undefined
var num = 20;
}
// 解析步骤:
// 1. 先将变量var num提升到最前面
var num;
// 2. 再将function fun()提升到前面
function fun(){
// 3. 再将function 函数里的var num 提升到函数内部最前面
var num;
console.log(num); // 因为变量num被提前,所以num没有赋值
num = 20;
}
// 4. 再将num = 10写出来;
num = 10;
// 5. 再将fun();写出来
fun();
// 6. 最终结果是 undefined
// 案例2:结果是几?
var num = 10;
function fun(){
console.log(num); // 结果是 undefined
var num = 20;
console.log(num); // 结果是20
}
fun();
// 案例3:结果是几?
var a = 18;
f1();
function f1(){
var b = 9;
console.log(a); // undefined
console.log(b); // 结果是 9
var a = '123';
}
// 案例4:结果是几?(重点:面试题)
f1();
console.log(c); // 调用全局变量c,结果是9
console.log(b); // 调用全局变量b,结果是9
console.log(a); // 无法调用函数内的变量a,所以报错
function f1(){
var a = b = c = 9;
console.log(a); // 结果是9
console.log(b); // 结果是9
console.log(c); // 结果是9
}
// 解析步骤:
// 1. 将function提升到最前
function f1(){
// 2. 将var a 提升到最前
var a;
a = 9;
b = 9; // 注意:函数内不使用var声明的变量是全局变量,所以b是全局变量
c = 9; // c也是全局变量
console.log(a); // 结果是9
console.log(b); // 结果是9
console.log(c); // 结果是9
}
// 3. 依次写f1
f1();
// 4. 写log
console.log(c); // 调用全局变量c,结果是9
console.log(b); // 调用全局变量b,结果是9
console.log(a); // 无法调用函数内的变量a,所以报错