深入理解js预编译过程

js预编译主要分为两种

一、全局预编译
思考一下这段代码在控制台输出什么?

   console.log(a)
   var a = 1
   function a(){}
   console.log(a)

像这种全局预编译我们只需要记住4个步骤:

1.创建全局活动对象VO

2.将变量声明作为活动对象的键且将其值赋值为undefined

3.寻找函数声明将函数名作为活动对象的键且值为函数本身,如果函数名和变量名重复则函数名覆盖变量名,值也会变成函数本身

4.预编译完成之后再执行script代码

   console.log(a)
   var a = 1
   function a(){}
   console.log(a)
 //根据以上步骤
 //1.创建活动对象VO
 //2.将变量声明作为VO的键,并且值为undefined,此时VO:{a:undefined}
 //3.寻找函数声明,这里function a(){}会覆盖之前VO对象中的a,此时VO:{a: f a(){}}
 //4.执行代码第一个console.log(a)输出f a(){},然后又将a赋值为1,最后第二个console.log(a)输出 1
 //最终浏览器输出的结果为 f a(){}  1

image.png

二、函数预编译

  function a(b,c){
   console.log(b)
   var b = 0
   console.log(b)
   var b = function(){
   console.log('bbb')
    }
   console.log(c)
   console.log(b)
  }
  a(1)

这是一个经典的函数预编译过程,思考一下这段代码在控制台输出什么?

这种函数预编译我们首先要明白一个概念:函数是在被执行的时候才会有预编译过程,这里第一行只是一个函数声明,第11行才是真正的执行函数,然后我们要知道函数预编译的步骤。

1.函数被执行时创建变量对象AO(active object)

2.寻找函数中的变量声明作为变量AO的键,值为undefined

3.将形参作为变量对象AO的键,值为undefined,如果与变量重名,则直接覆盖就行

4.将实参的值赋值给形参,此时AO对象中某些以形参为键的值会因实参的赋值而发生变化

5.寻找函数声明作为变量对象AO的键值为undefined

6.执行函数

function a(b,c){
  console.log(b)
  var b = 0
   console.log(b)
     var b = function(){
       console.log('bbb')
     }
       console.log(c)
        console.log(b)
      }
      a(1)
 //函数预编译  注意:是在函数执行的时候进行函数的预编译
        //1.创建变量对象Ao:{}
        //2.寻找变量声明作为Ao的键Ao:{b:undefined}
        //3.形参作为变量对象AO的键Ao:{b:undefined,c:undefined}
        //4.将实参的值赋值给形参Ao:{b:1,c:undefined}
        //5.寻找函数声明作为Ao的键,值为undefined 这里没有函数声明 Ao:{b:1,c:undefined}
        //6.函数执行 依次输出 1,0,undefined,f(){console.log('bbb')}

image.png

最后留给大家一个小练习题,试一下下面这段代码输出的是什么吧!

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)
  • 11
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值