likes
comments
collection
share

你真的了解JS的预编译吗?

作者站长头像
站长
· 阅读数 49

前言

在JS中,预编译是至关重要的一环,它能够帮助我们理解变量的作用域,函数声明等,提高代码的执行效率,增强代码的可读性。今天让我们细说一下JS预编译规则。

一、声明提升

变量声明,声明提升 举个例子:

console.log(a)
var a = 1

你真的了解JS的预编译吗?

这段代码的输出结果为undefined,而不是报错。为什么呢?这就是声明提升的缘故。因为声明提升,上述代码在V8引擎中其实是这样被执行的。

你真的了解JS的预编译吗?

变量a已经被声明了,然后输出a,但是此时变量a还没有被赋值,所以输出undefined,而不是报错。

函数声明,整体提升 举个例子:

foo()
function foo(){
console.log(3)
}

这段代码为什么不会报错呢?因为函数声明,整体提升。这段代码在V8引擎中是这样执行的。

你真的了解JS的预编译吗?

函数中的预编译

函数中的预编译主要分为以下步骤:

🐾 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
// }

故输出结果如下;

你真的了解JS的预编译吗?

想必现在大家应该掌握了函数的预编译步骤,让我们再练习一题:

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)

输出结果是什么呢?答案是:

你真的了解JS的预编译吗?

具体分析步骤如下,可供参考:

// 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
// }

输出结果如下:

你真的了解JS的预编译吗?

让我们再看一段代码加强巩固:

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
// }

输出结果如下:

你真的了解JS的预编译吗?

总结

正确地理解预编译可以帮助我们理解作用域的规则,变量和函数声明的提升,预防常见的错误。希望大家先理解后实战。今天的分享到此结束,感谢你看到了最后。

转载自:https://juejin.cn/post/7372765277459316746
评论
请登录