预编译 - AO篇

步骤

  1. 创建AO对象
  2. 找形参和变量的声明,作为AO对象的属性名,值为 undefined
  3. 实参和形参相统一
  4. 找函数声明,若与变量名称一致则覆盖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
function fn(a, c) {
console.log(a)
var a = 123
console.log(a)
console.log(c)
function a() { }
if(false){
var d = 789
}
console.log(d)
console.log(b)
var b = function() {}
console.log(b)
function c() {}
console.log(c)
}
fn(1, 2)
  1. 首先创建AO对象

    1
    2
    3
    AO:{

    }
  2. 找形参和变量的 声明 ,作为AO对象的属性名,值为 undefined

    1. 从上往下依次有:fn(a, c) 中的形参 a 和 c
    1
    2
    3
    4
    AO: {
    a: undefined,
    c: undefined
    }
    1. var d = 789 中的 d
    1
    2
    3
    4
    5
    AO: {
    a: undefined,
    c: undefined,
    d: undefined
    }
    1. var b = function() {} 中的 b
    1
    2
    3
    4
    5
    AO: {
    a: undefined,
    c: undefined,
    d: undefined
    }
  3. 找实参和形参相统一

    形参是fn(a, c)中的形参 a 和 c,这里的 a 和 c 的实参是 fn(1, 2) 传入的 1 和 2

    所以此时的AO对象为:

    1
    2
    3
    4
    5
    6
    AO:{
    a: undefined, => 1
    c: undefined, => 2
    d: undefined,
    b: undefined
    }
  4. 找函数声明,若与变量名称一致则覆盖

    函数的声明从上往下依次有:

    • function a() { }
    • function c() {}

    所以此时的AO对象会变成:

    1
    2
    3
    4
    5
    6
    AO:{
    a: undefined, => 1 => function a() {}
    c: undefined, => 2 => function c() {}
    d: undefined,
    b: undefined
    }

    这一步也导致了常说的函数的 “变量提升”,其实就是执行顺序,相同的变量名,后面的覆盖前面的

    注意:var b = function() {} 这里并不是声明一个名为 b 的函数,而是声明一个匿名函数,变量 b 指向这个函数的入口,所以这里的 b 不算是函数的声明

  5. 运行输出打印结果

    执行时是逐行解释的,所以根据执行顺序和AO对象,可以写出对应的打印结果:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    function fn(a, c) {
    console.log(a) // function a(){}
    var a = 123
    console.log(a) // 123
    console.log(c) // function c(){}
    function a() { }
    if(false) {
    var d = 789
    }
    console.log(d) // undefined
    console.log(b) // undefined
    var b = function() {}
    console.log(b) // function() {}
    function c() {}
    console.log(c) // function c(){}
    }
    fn(1, 2)



    /**
    * 1. 创建ao对象
    * 2. 找形参和变量的声明,作为ao对象的属性名,值为undefined
    * 3. 实参和形参相统一
    * 4. 找函数声明,若与变量名称一致则覆盖
    *
    * AO:{
    a: undefined 1 function a(){}
    c: undefined 2 function c(){}
    d: undefined
    b: undefined
    }
    *
    * 5. js逐行解释执行
    * AO:{
    a: undefined 1 function a(){} 123
    c: undefined 2 function c(){}
    d: undefined
    b: undefined function() {}
    }
    *
    *
    *
    */