预解析
一、 预解析
1.1、概述
- JavaScript 代码的执行是由浏览器中的 JavaScript 解析器来执行的
- JavaScript 解析器执行 JavaScript 代码的时候,分为两个过程:预解析过程和代码执行过程
- 预解析分为变量预解析(变量提升)和函数预解析(函数提升)
- 代码执行是按代码的书写顺序从上到下执行的.
1.2、操作原理
- 预先读取JavaScript中的所有程序内容,找到所有 var 和 function 关键词 来进行预解释和预解析
- 告诉计算机程序,有哪些变量是使用 var 关键词声明
- 如果提前使用 var 声明的变量,告诉计算机程序,这个变量已经存在,只是当前没有赋值,执行结果是undefined,不会报错
- 如果是使用function 声明的函数,告诉计算机程序,这个函数已经存在,并且告诉计算机这个函数的内存地址,可以正常调用使用这个函数。
二、变量预解析
- 变量预解析就是把所有的变量声明提升到当前作用域的最前面,不提升赋值操作
例如:
console.log(num);
var num = 10;
// 相当于执行
var num;
console.log(num);//undefined
num = 10;
三、函数预解析
- 函数预解析就是把所有的函数声明提升到当前作用域的最前面,不调用函数
- 用function关键字声明的函数遵循函数预解析规则,会提升该函数声明
- 使用变量接收函数的函数表达式的声明方式,会提升该变量的声明,但是该变量此时还没有接收函数,使用变量名调用函数会报错
- 函数表达式调用必须写到函数表达式的下面
例如:
var num = 10;
fun();
function fun() {
console.log(num);
var num = 20;
}
// 相当于执行
var num;
function fun() {
var num;
console.log(num);
num = 20;
}
num = 10;
fun(); //结果是 undefined
四、预解析案例
案例1:
var a = 25;
function abc() {
alert(a); //结果是 undefined
var a = 10;
}
abc();
预解析结果:
var a; // 在全局作用域里提升变量
function abc() { // 在全局作用域里提升函数
var a; // 在局部作用域里提升变量
alert(a); // a 的值是 undefined
a = 10; // 在局部作用域里给变量赋值
}
a = 25; // 给变量赋值
abc(); // 调用函数
案例2:
console.log(a);
function a() {
console.log('aaaaa');
}
var a = 1;
console.log(a);
预解析结果:( 在预解析的过程中如果函数和变量的名字相同,此时函数优先 )
var a; //全局作用域里提升变量
function a() { //全局作用域里提升函数
console.log('aaaa');
}
console.log(a); // 输出函数 a 在预解析的过程中如果函数和变量的名字相同,此时函数优先
a = 1; // 给变量赋值
console.log(a); // 输出变量 a
案例3:
var a = 18;
f1();
function f1() {
var b = 9;
console.log(a);
console.log(b);
var a = '123';
}
预解析结果:
var a; // 全局作用域中提升变量
function f1() { // 全局作用域中提升函数
var b; // 局部作用域中提升变量
var a; // 局部作用域中提升变量
b = 9; // 局部作用域中给变量赋值
console.log(a); // a 的值为 undefined
console.log(b); // b 的值为 9
a = '123'; // 局部作用域中给变量赋值
}
a = 18; // 全局作用域中给变量赋值
f1(); // 调用函数
|