预编译

115 阅读1分钟

预编译

前情提要:

  1. imply global(暗示全局变量):即任何变量,如果变量未经声明就赋值,此变量就为全局(window)对象所有。
  2. 一切声明的全局变量,都是window的属性。(就相当于给window对象添加了一个属性,window就是全局的域)

函数预编译四部曲

  1. 创建AO(activation object)对象(执行期上下文)
  2. 找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
  3. 将实参和形参统一
  4. 在函数体里面找函数声明,值赋予函数体

下面是例子⬇️

function fn(a) {
    console.log(a); //function a(){}
    var a = 123;
    console.log(a); // 123
    function a(){}
    console.log(a) //123
    var b = function(){}
    console.log(b) //function(){}
    function d(){}
 }
 fn(1)
 //第二步
 AO{
     a : undefined,
     b : undefined
 }
 //第三步
 AO{
     a : 1,
     b : undefined
 }
 //第四步
 AO{
     a : function a(){},
     b : undefined,
     d : function d(){}
 }

全局预编译

  1. 创建GO(global object)对象
  2. 找变量声明,将变量名作为GO属性名,值为undefined
  3. 在函数体里面找函数声明,值赋予函数体

全局就是比函数预编译少一个形参的步骤。 ⬇️两种预编译结合起来的顺序大概就是:

console.log(test) //打印下面这个test函数体
function test(test){
    console.log(test) //function test(){}  
    var test = 234
    console.log(test) //234
    function test(){}
}
test(1)
//先生成GO
GO{
    test : function test(test){
                console.log(test)
                var test = 234
                console.log(test)
                function test(){}
            }
}
//执行函数的前一刻,发生预编译,生成AO
AO{
    test: function test(){}  
}

可以看到函数会先找自己AO对象中的属性,如果没有才会去找GO里有没有。