预编译现象:

    // 函数声明整体提升
    test(); // 不报错, 打印111
    function test(){ console.log(111) }
    // 变量 声明提升
    console.log(a) // 不报错,打印undefined
    var a = ‘111’


    预编译前奏:**
    imply global暗示全局变量:即任何变量,如果变量未经声明就赋值。此变量就是全局对象所有(即window)。
    a = 10 ==> window.a = 10

    function test () {
    var a = b = 123;
    }
    test()
    console.log(typeof a, b) // undefined; 123


    预编译**

    function fn (a) {
    console.log(a); // function a() {}
    console.log(b); // undefine
    var a = 123;
    console.log(a); // 123
    function a () {}
    console.log(a); // 123
    var b = function () {}
    console.log(b) // function b() {}
    function d () {}
    }

    fn (1)

    预编译发生在函数执行的前一刻;

    函数预编译四部曲:**

    1. 创建AO对象
    2. 找函数形参和变量声明,将变量和形参名作为AO属性名,值为undefined;
      AO {
      a: undefined,
      b: undefined
      }
    3. 将实参值与形参统一
      AO {
      a: 1,
      b: undefined
      }
    4. 在函数体里面找函数声明,值赋值函数体
      AO {
      a: function a () {},
      b: undefined,
      d: function d () {}
      }

    预编译完成后,在执行fn(1),预编译中的编译的语句后来是不执行的。

    全局预编译:**

    1. 生成了一个GO对象(GO === window)
    2. 找变量声明,值为undefined,提升函数声明;

    预编译顺序:先生成GO,再生成AO;

    练习题:

    var str = false + 1
    console.log(str); // 1
    typeof(a) && -true + (+undefined) + “” // NaN;
    !!” “ + !!”” + !!false // 1


    最后……
    执行期上下文定义:**
    当函数执行时,会创建一个称为执行期上下文的内部对象。一个执行期上下文定义了一个函数执行时的环境,函数每次执行时对应的执行上下文都是独一无二的,所以多次调用一个函数会导致创建多个执行上下文,当函数执行完毕,执行上下文被销毁。