一、预解析
1、概述
JavaScript 代码的执行是由浏览器中的 JavaScript 解析器来执行的。
JavaScript 解析器执行 JavaScript 代码的时候,分为两个过程:预解析过程和代码执行过程。
2、过程
-
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
- 把函数的声明提升到当前作用域的最前面,只会提升声明,不会提升调用。
- 先后规则:先提升 var,在提升function
- 把变量的声明提升到当前作用域的最前面,只会提升声明,不会提升赋值。
二、解析规则
1、全局解析与函数内部解析规则一致
-
- 变量提升:定义变量的时候,变量的声明会被提升到作用域的最上面,变量的赋值不会提升。
- 函数提升:JavaScript 解析器首先会把当前作用域的函数声明提前到整个作用域的最前面
三、案例
案例1:
1 var a = 25;
2 function abc (){
3 alert(a); //undefined
4 var a = 10;
5 }
预解析结果:
1 var a; // 在全局作用域里提升变量
2 function abc() { // 在全局作用域里提升函数
3 var a; // 在局部作用域里提升变量
4 alert(a); // a 的值是 undefined
5 a = 10; // 在局部作用域里给变量赋值
6 }
7 a = 25; // 给变量赋值
8 abc(); // 调用函数
案例2:
1 console.log(a);
2 function a() {
3 console.log('aaaaa');
4 }
5 var a = 1;
6 console.log(a);
预解析结果:( 在预解析的过程中如果函数和变量的名字相同,此时函数优先 )
1 var a; //全局作用域里提升变量
2 function a() { //全局作用域里提升函数
3 console.log('aaaa');
4 }
5
6 console.log(a); // 输出函数 a 在预解析的过程中如果函数和变量的名字相同,此时函数优先
7 a = 1; // 给变量赋值
8 console.log(a); // 输出变量 a
案例3:
1 var a = 18;
2 f1();
3 function f1() {
4 var b = 9;
5 console.log(a);
6 console.log(b);
7 var a = '123';
8 }
预解析结果:
1 var a; // 全局作用域中提升变量
2 function f1() { // 全局作用域中提升函数
3 var b; // 局部作用域中提升变量
4 var a; // 局部作用域中提升变量
5 b = 9; // 局部作用域中给变量赋值
6 console.log(a); // a 的值为 undefined
7 console.log(b); // b 的值为 9
8 a = '123'; // 局部作用域中给变量赋值
9 }
10 a = 18; // 全局作用域中给变量赋值
11 f1(); // 调用函数
案例4:
1 f1();
2 console.log(c);
3 console.log(b);
4 console.log(a);
5 function f1() {
6 var a = b = c = 9;
7 console.log(a);
8 console.log(b);
9 console.log(c);
10 }
预解析结果:
1 function f1() { // 全局作用域中提升函数
2 var a; // 局部作用域中提升变量
3 a = b = c = 9; // 局部作用域中给变量赋值
4 console.log(a);
5 console.log(b);
6 console.log(c);
7 }
8 f1(); // 调用函数
9 console.log(c);
10 console.log(b);
11 console.log(a);
注意:
其中 函数 f1 内部的 var a = b = c = 9; 等价于 var a = 9; b = 9; c = 9; 其中 a 是一个 函数内的局部变量,b 和 c 是全局变量。