关于JavaScript的预编译解答

216 阅读3分钟

一、案例引入

var global = 100
function fn() {
    console.log(global)
}
fn()

在面对HR,面试官问你代码执行结果时,看到这个代码,你可能脱口而出 '100'!紧接着问到原因时,也许你同样能快速答出内部代码找不到此变量,往外部代码找。当然是对的,但在面试官眼中可能并不太满意,换句话说,不够底层!

二、详谈预编译

何为预编译? 代码在执行前进行编译操作,用于确定代码之间的各种关联!

Javascript的预编译,仅在代码执行前的短时间内完成。而预编译分为两种。为全局预编译函数体内的预编译。而整个代码的执行步骤为: 全局代码预编译->全局代码执行->函数体内预编译->函数体内代码执行

接下来我们将根据一份看似复杂的代码来人脑执行(可以偷偷用电脑跑)

1714147523794.png

三、代码引入及照着步骤跑!

function test(a, b) {
    console.log(a);//1
    c = 0
    var c;
    a = 3
    b = 2
    console.log(b);//2
    function b() {}
    console.log(b);//2
  }
  test(1)
}

全局预编译三小点

1 创建GO对象
GO {
//为空
}
2 找变量声明,将变量名作为GO属性名,值为undefined
GO {
//全局无变量声明,依旧空
}
3 在全局找函数声明,将函数名作为GO的属性名,值为该函数体
GO {
test: function(){}
}

全局代码执行

执行test(1) (此时注意,函数只有调用才被执行,故直接到test(1))

现在可犯了难,test(1)是什么呢?此时我们想起刚刚的步骤,回到函数的预编译!!!

函数体的预编译四小点

1创建一个AO对象
AO {
为空
}
2找形参和变量声明,将形参和变量名作为AO属性名,值为undefined
AO {
a: undefined
b: undefined
c: undefined
}
3形参和实参统一
AO {
a: undefined->1
b: undefined
c: undefined->0
}
4在函数体内找函数声明,将函数名作为AO属性名,值为函数体
AO {
a: undefined->1
b: undefined->function b(){}
c: undefined->0
}

函数体代码执行

AO {
a: undefined->1->3
b: undefined->function b(){}->2
c: undefined->0
}

四、总结

完整地按照此步骤进行:全局代码预编译->全局代码执行->函数体内预编译->函数体内代码执行,相信面试官对你会刮目相看噢 另外第一次创作码字不易,大家点点关注和点赞!!!谢谢啦

f0fd23c3696cd5f29ff0e4fb1a5f56b.png


一些概念和可能的疑难解答

  • AO对象:Activation object活动对象

  • GO对象:Global object全局对象

  • c = 0 不是声明变量语句,只是赋值

  • 函数只有被调用才会执行,否则往下走就是,所以此代码全局执行时直接到test(1)

  • 此代码的执行结果为 1 2 2;至于为什么a不是3,那是console.log(a)在a变为3的时候已经执行啦

  • 但其实a b c的值正如最后一段AO所示变成了3 2 0;不信的话执行下面的代码

function test(a, b) {
    console.log(a);//1
    c = 0
    var c;
    a = 3
    b = 2
    console.log(b);//2
    function b() {}
    console.log(b);//2
  
    console.log(a)
    console.log(b)
    console.log(c)
  }
  test(1)