预编译

115 阅读1分钟

首先,预编译有四个步骤:

  1. 创建AO对象
  2. 找形参和变量声明,将变量声明和形参名作为AO属性名,值为undefined
  3. 将实参值和形参统一
  4. 在函数体里面找函数声明,值赋予函数体

以下代码我们来详细解读是如何进行预编译

function fn(a){
    console.log(a)
    var a = 123
    console.log(a)
    function a(){}
    console.log(a)
    var b = function b(){}
    console.log(b)
    function d(){}
}
fn(1)
  1. 首先遇到函数fn(1),进入到函数fn内,创建AO对象
  2. 在函数体内,找形参和变量声明,将变量声明和形参名作为AO属性名,值为undefined
AO:{
    a:underfind,
    b:underfind,
    d:underfind
}
  1. 将实参值和形参统一
AO:{
    a:1,
    b:underfind,
    d:underfind
}

4.在函数体里面找函数声明,值赋予函数体

AO:{
    a:function a(){},
    b:underfind,
    d:function d(){}
}

然后依次执行函数体内的语句 遇到console.log(),打印函数function a(){},遇到var a = 123,将a赋值123,又遇到console.log(),打印123,遇到 var b = function b(){},将b赋值function b(),遇到console.log(),将函数打印出来,执行完毕。

再举个例子:

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

遇到global = 100,在全局中定义一个GO,赋值underfind,变量声明提升,所以即使没有var一个global,后面var了也能生效,遇到fn函数,进入到fn函数体内,并创建一个AO,将函数体内的global赋值underfind,然后按顺序执行,打印fn内的第一个global为underfind,第二个为200,因为在执行函数的时候,会优先找函数内部的global,如果没有,才会去上级找。