js预编译(全局预编译/函数预编译)

1.预编译

预编译是上下文创建之后, js代码执行前的一段时期, 在这个时期, 会对js代码进行预处理。

2.全局预编译

全局上下文创建后,会生成变量对象VO:var变量-》函数-》同名函数覆盖变量名

  1. VO首先寻找变量声明,将var声明的变量作为VO对象的属性名,值为undefined。
  2. 然后寻找函数声明,属性值为函数本身
  3. 如果函数名与变量名冲突,函数声明会将变量声明覆盖。
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

3.函数预编译

函数上下文创建后,会生成变量对象AO:函数预编译: var变量-》形参-》实参赋值给形参-》函数-》同名函数覆盖变量声明

  1. 寻找变量声明, 变量名作为AO对象的属性名, 属性值置为 undefined
  2. 寻找形参, 形参名作为AO对象的属性名, 属性值置为 undefined
  3. 将实参的值赋予形参, 即替换 AO对象中形参的属性值
  4. 寻找函数声明, 函数名作为AO对象的属性名, 属性值为函数本身
  5. 如果函数名与变量名冲突, 函数声明会将变量声明覆盖 

注意:函数预编译时,如果有判断条件里面的变量声明,无论判断条件真假,都会进行预编译。

如下:这里函数里面的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的函数体

4.全局预编译和函数预编译整个流程

  1. 全局预编译和局部预编译都有时,是先进行全局预编译,预编译完成后会逐行执行,比如一些变量赋值,打印;
  2. 函数预编译是在函数被调用前才进行预编译,编译完成后再开始执行;
  3. 执行是首先在自己作用域里面查找属性,有属性没有赋值直接返回undefined ,没有定义属性从全局查找,查找不到返回undefined

5.预编译面试题

        // 面试题
        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

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值