小白必看———JavaScript中的预编译

78 阅读2分钟

在学习js的过程中,我们或多或少都会了解到:

var 声明的变量会存在声明提升
函数声明会整体提升

可是为什么它们会存在声明提升呢?不知你们有没有想过这个问题。

预编译

它们之所以会出现声明提升,正是因为有着预编译的作用,var声明的变量以及函数声明才会提升。

预编译的种类

预编译和变量声明一样,有着全局预编译和局部预编译(即函数预编译);全局预编译发生在页面加载完成时执行,而函数预编译发生在函数执行的前一刻。

全局预编译

全局预编译的步骤分为:

  1. 创建GO对象(Global Object)
  2. 找变量声明,将变量声明作为GO的属性名,值赋予undefined
  3. 在全局找函数声明,将函数名作为GO对象的属性名,值赋予函数体

让我们来看一下下面这段代码:

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

接下来我们按照前面的步骤来详细分析它的预编译的执行过程:
1.创建一个GO对象

GO ={
    // 对象内容为空
}

2.找变量声明,并赋值为undefind

GO ={
      global: undefind,
    }

3.找函数声明,并赋值为函数体

GO ={
     global: undefind,
     fn: function fn(){}
     }

4.按顺序执行代码,最后GO对象就变成了

GO ={
     global: 100,
     fn: function fn(){}
     }

函数预编译

函数预编译的步骤分为:

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

同样我将用下面一段代码来解释

function fn(a) {
  console.log(a); 
  var a = 123
  console.log(a); 
  function a() {}
  console.log(a);  
  var b = function() {} //函数表达式
  console.log(b);   
  function d() {}
  var d = a
  console.log(d);  
}
fn(1)

接下来我按照前面的步骤来逐步分析它的预编译执行过程:
1.创建AO对象

AO ={
    // 空对象
}

2.找形参和变量声明,将形参和变量声明作为AO的属性名,值赋予undefine

AO ={
    a: undefined
    b: undefined
    d: undefined
}

3.将形参和实参统一

AO ={
    a: 1
    b: undefined
    d: undefined
}

4.在函数体内找函数声明,将函数名作为AO对象的属性名,值赋予函数体

AO ={
    a: function a(){}
    b: function b(){}
    d: function d(){}

函数按顺序执行代码,最终AO对象就变成了:

AO ={
    a: 123
    b: function b(){}
    d: 123

结语

综上,在学习预编译时,我们要熟练的去掌握全局预编译和函数预编译的几个步骤,这样对于我们后面的进一步学习有着很大的作用。

image.png