你真的了解JS的预编译吗?
前言
在JS中,预编译是至关重要的一环,它能够帮助我们理解变量的作用域,函数声明等,提高代码的执行效率,增强代码的可读性。今天让我们细说一下JS预编译规则。
一、声明提升
① 变量声明,声明提升
举个例子:
console.log(a)
var a = 1
这段代码的输出结果为undefined,而不是报错。为什么呢?这就是声明提升的缘故。因为声明提升,上述代码在V8引擎中其实是这样被执行的。
变量a已经被声明了,然后输出a,但是此时变量a还没有被赋值,所以输出undefined,而不是报错。
② 函数声明,整体提升
举个例子:
foo()
function foo(){
console.log(3)
}
这段代码为什么不会报错呢?因为函数声明,整体提升。这段代码在V8引擎中是这样执行的。
函数中的预编译
函数中的预编译
主要分为以下步骤:
🐾 1.创建函数的执行上下文对象AO(Activation Object)
🐾 2.找形参和变量声明,将形参和变量名作为AO的属性名,值为undefined
🐾 3.将实参和形参统一
🐾 4.在函数体内寻找函数声明,将函数名作为AO的属性名,值赋予函数体
让我们一起看下列代码一起分析:
function fn(a){
console.log(a); // function a(){}
var a = 123
console.log(a); // 123
function a(){}
console.log(a); // 123
var b = function(){}
console.log(b); // function b(){}
function d(){}
var d = a
console.log(d);
}
fn(1)
想要得到输出的结果,首先按步骤进行预编译。先创建函数的AO,找到形参和变量声明(a ,b ,d)作为AO的属性名,然后将实参和形参统一,最后在函数体内找到函数声明(function a(){} ,function b(){}),将函数名作为AO的属性名,值赋予函数体。
// AO:{
// a: undefined -> 1 -> function a(){} -> 123
// b: undefined -> function (){}
// d: undefined -> function d(){} -> 123
// }
故输出结果如下;
想必现在大家应该掌握了函数的预编译步骤,让我们再练习一题:
function fn(a,b){
console.log(a); // 1
c = 0
var c
a = 3
b = 2
console.log(b);
function b(){}
console.log(b);
}
fn(1)
输出结果是什么呢?答案是:
具体分析步骤如下,可供参考:
// AO:{
// a: undefined -> 1 -> 3
// b: undefined -> function b(){} -> 2
// c: undefined -> 0
// }
全局的预编译
全局的预编译
分为以下步骤:
🎈 1.创建全局执行上下文GO(Global Object)
🎈 2.找变量声明,声明变量为Global的属性部门,值为undefined
🎈 3.在全局寻找函数声明,函数名作为Global的属性名,值为函数体
让我们一起分析以下代码:
var global = 100
function fn(){
console.log(global);
}
fn()
首先创建全局执行上下文GO,然后找变量声明(global),声明变量为Global的属性部门,值为undefined,最后在全局寻找函数声明(fn())作为Global的属性名,值为函数体
// GO:{
// global: undefined -> 100
// fn(): function{}
// }
// AO:{
// global: undefined -> 100
// }
输出结果如下:
让我们再看一段代码加强巩固:
global = 100
function fn(){
console.log(global); //undefined
global = 200
console.log(global); // 200
var global = 300
}
fn()
var global
具体分析步骤如下可供参考:
// GO:{
// global: undefined -> 100
// fn(): function{}
// }
// AO:{
// global: undefined -> 200 -> 300
// }
输出结果如下:
总结
正确地理解预编译可以帮助我们理解作用域的规则,变量和函数声明的提升,预防常见的错误。希望大家先理解后实战。今天的分享到此结束,感谢你看到了最后。
转载自:https://juejin.cn/post/7372765277459316746