JavaScript基础-预编译

104 阅读2分钟

1. 概念解释

在JS预编译中,主要涉及两个概念:AO(Activation Object)和GO(Global Object)

  • AO:Activation Object 直译过来就是活跃对象,专业点就是函数执行期上下文,指的是函数的作用域
  • GO:Global Object 全局对象,也叫全局上下文,可以简单理解成是JS运行的环境,比如浏览器或者node

2. AO、GO生成步骤

2.1 AO函数执行期上下文

  1. 寻找形参和函数体的变量声明
  2. 实参给形参赋值
  3. 寻找函数体的函数声明
  4. 执行函数体
function test(a) {
    return a;
    a = 1;
    function a(){}
    var a = 2;
}
console.log(test(0)); // function a(){}
1. 寻找形参和函数体的变量声明
AO = {
   a: undefined 
}

2. 实参给形参赋值
AO = {
   a: undefined 
      0
}

3. 寻找函数体的函数声明
AO = {
   a: undefined 
      0
      function a(){}
}

4. 执行函数体
AO = {
   a: undefined 
      0
      function a(){}
      1 -> 2
}

return a是在a = 1之前,因此返回了function a(){}

2.2 GO 全局上下文

  1. 寻找变量声明
  2. 函数声明
  3. 执行
console.log(a); // undefined
var a = 1;
1. 寻找变量声明
GO = {
    a: undefined
}

2. 函数声明
没有函数声明,故GO = { a: undefined }

3. 执行
GO = {
    a: undefined
       1
}
var a = 1;其实是两个步骤,先声明变量a,然后给a赋值为1,打印a是在赋值之前,因此打印结果为undefined

2.3 AO、GO综合练习

a = 1;
function test(e) {
  function e() {}
  arguments[0] = 2;
  console.log(e); // 2
  if (a) {
    var b = 3;
  }
  var c;
  a = 4;
  var a;
  console.log(b); // undefined
  f = 5;
  console.log(c); // undefined
  console.log(a); // 4
}
var a;
test(1);

分析:

在执行该段代码前,JS先进行预编译,生成GO,AO对象

1. 在test被定义前,只有GO
GO = {
    a: undefined
    test: function test(){}
}

2. 在test执行前,此时有了test的函数上下文AO,f为全局变量,因此f在GO中
AO = {
    e: undefined
       1
       function e() {}
    b: undefined
    c: undefined
    a: undefined
       4
}
GO = {
    a: undefined
    test: function test(){}
    f: undefined
}

3. 执行,在执行是发现AO里有a,因此不会找GO里的a,此时a=undefined,因此b = 3不会执行
AO = {
    e: undefined
       1
       function e() {}
       2
    b: undefined
       3
    c: undefined
    a: undefined
       4
}
GO = {
    a: undefined
       1
    test: function test(){}
    f: undefined
       5
}

最终打印结果:

2
undefined
undefined
4