预编译是上下文创建之后, js代码执行前的一段时期, 在这个时期, 会对js代码进行预处理。
全局上下文创建后,会生成变量对象VO:var变量-》函数-》同名函数覆盖变量名
- function a(b, c) {
- console.log(b);
- var b = 0
- console.log(b);
- var b = function () {
- console.log('bbbb')
- }
- console.log(c);
- console.log(b);
- }
- a(1)
全局预编译分析:
- // 第一步:寻找变量声明var,将变量名作为属性名,将值设置为undefined
- VO {
- a: undefined
- }
- // 第二步:寻找函数声明,属性值为函数本身
- // 第三步:函数名和变量名冲突,函数声明会覆盖变量声明
- VO {
- a: undefined-> function a() { }
- }
- //执行结果: function a() { }, 100
函数上下文创建后,会生成变量对象AO:函数预编译: var变量-》形参-》实参赋值给形参-》函数-》同名函数覆盖变量声明
注意:函数预编译时,如果有判断条件里面的变量声明,无论判断条件真假,都会进行预编译。
如下:这里函数里面的var tmp也会进行预编译
- function a(b, c) {
- console.log(b);
- var b = 0
- console.log(b);
- var b = function () {
- console.log('bbbb')
- }
- console.log(c);
- console.log(b);
- }
- a(1)
函数预编译解析:
- // 第一步:寻找函数中的变量声明,将变量名作为属性名,将值设置为undefined
- AO : {
- b: undefined,
- }
- // 第二步:寻找形参
- AO : {
- b: undefined,
- c: undefined,
- }
- // 第三步:将实参传给形参(b变成了1)
- AO : {
- b: undefined -> 1,
- c: undefined,
- }
-
- // 第四步:寻找函数声明(此处没有)
- // 第五步:如果函数名与变量名冲突, 函数声明会将变量声明覆盖(此处没有)
- // 执行结果:1 ,0,(将函数赋值给b),undefined, b的函数体
- // 面试题
- function fn(a, c) {
- console.log(a)
- var a = 123
- console.log(a)
- console.log(c)
- function a() { }
- if (false) {
- var d = 678
- }
- console.log(d)
- console.log(b)
- var b = function () { }
- console.log(b)
- function c() { }
- console.log(c)
- }
- fn(1, 2)
预编译解析:
- // 函数预编译: var变量-》形参-》实参赋值给形参-》函数-》同名函数覆盖变量声明
- AO:{
- a: undefined->1->funA,
- d: undefined,
- b: undefined-》funB,
- c: 2->funC
- }
- // 执行结果:funA,123,funC,undefined,undefined,funB,funC