JavaScript——关于预编译的基础讲解

121 阅读2分钟

预编译

关JavaScript这门弱类型的动态语言我们都知道的是var声明的变量会声明提升,函数的声明也会整体提升。那为什么会存在这种声明呢?这就不得不提到JavaScript的预编译了,预编译就是在一段代码的执行之前编译器对代码会进行整理,使代码变成处理器能够读懂的样子。

预编译存在两种情况

  1. 预编译发生在函数体内时

  2. 预编译发生在全局时

1. 预编译发生在函数体内时

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

例如

function fn(){
    console.log(global);//underfind
    global=200;
    console.log(global);//200
    var global =300;
}
fn()
var global;

它的AO对象为:

AO={
     global:undefined => 200 => 300
 }

2. 预编译发生在全局

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

例如

function fn(){
    console.log(global);//underfind
    global=200;
    console.log(global);//200
    var global =300;
    }
    fn()
var global;

它的GO对象为

GO ={
     global:  underfind => 100
     fn:  function fn(){}  
 }

总结

当这段代码执行时,在第三行代码打印global的值时,首先先访问AO对象,此时发现AO对象中存在global且此时的global经过预编译它的值为underfind,所以第一个打印输出underfind。当执行到第二个打印时,global经过第三行代码的赋值操作变为了200,所以第二个打印输出的结果是200。

需要注意的是,在函数执行过程中在对变量进行查找时需先从AO对象中查找,如果AO对象中找不到这个变量才会到GO对象中去查找。