理解预编译变量提升

533 阅读2分钟

预编译

  1. 检查通篇的语法是否有错误
  2. 预编译过程
  3. 解释一行,执行一行

注意:函数声明整体提升定义,变量只有声明提升,赋值是不提升的

GO =》全局的执行期上下文

 //暗示全局变量 imply global variable
    var a = 1              //a = window.a
    b = 2                  //b = window.b 
    console.log(window.a); 
                           
                           //a和b实质上等价于
                           //  window = {
                           //            a = 1,
                           //            b = 2
                           //           }

由此看出如果变量(b)未被声明就赋值了的话,该变量默认就是全局变量(暗示全局变量的体现)他的所有权在浏览器里归window全局对象。 Windows可以理解为全局域

 function test() {
      var a = b = 10;
    }
    test();
    
    console.log(b);//1
    console.log(window.a);//undefined
    console.log(a);//Uncaught ReferenceError: a is not defined

由此看出在函数内部如果没给变量声明直接赋值的话就自动声明到全局对象里了

先看看这个例子:

解释:
GO  => global object (全局上下文)  GO===window
1、找变量
2、找函数声明
3、执行
GO = {
    a:undefined -> function a() {} -> 1;//所以最后输出1
}

AO =》 函数的执行期上下文(可理解为一个即时的存储容器,正常情况下用完销毁)

解释:
AO => activation object 
活跃对象,函数上下文
1. 寻找形参和变量声明
2. 实参值赋值给形参
3. 找函数声明,赋值(定义)
4. 执行
AO = {
    a: undefined -> 
    2 -> 
    function a() {} -> 
    1,
    b: undefined -> function() {},
    d: function d() {}
}

你可以继续看看下面的例子

function test(a, b) {
      console.log(a);   //1
      c = 0;
      var c;
      a = 5;
      b = 6;
      console.log(b);  //6
      function b() {};
      function d() {};
      console.log(b);  //6
    }
    
    test(1);
function test() {
      return a;
      a = 1;
      function a() {}
      var a = 2;
    }
    console.log(test()); // ƒ a() {}

GO和AO结合来看:

例题一

    a = 1;
    function test() {
      console.log(a); //undefined  ,因为这个时刻a = undefined所以不会拿外面GO的1.
      a = 2;
      console.log(a); //2
      var a = 3;
      console.log(a); //3
      
    }
    test();
    var a;
    //解释:
    /* GO = {
              a: undefined ->
                  1,
              test: function test() {...}
       }

       AO = {
              a: undefined ->
                 2 ->
                 3
       }
    */

例题二

function test() {
      console.log(b);  //undefined
      if(a) {
        var b = 2;
      }
      c = 3;
      console.log(c);  //3
    }
    var a;
    test();
    a = 1;
    console.log(a);  //1
    
    //解释:
    /* GO = {
              a: undefined ->
                  1,
              test: function test() {...}
              c = 3
       }

       AO = {
              b: undefined 
       }
    

例题三

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)
    console.log(a); //1
    console.log(f); //5

注意:也许你也听说过VO,VO是定义的全局对象,GO是全局对象,包括window上的。