美文网首页
JavaScript预编译

JavaScript预编译

作者: Lnevan | 来源:发表于2021-03-13 11:26 被阅读0次

    预编译前奏

    • 变量声明提升
      • 通过var定义(声明)的变量,在定义语句之前就可以访问到
      • 值:undefined
    • 函数声明提升
      • 通过function声明的函数,在之前就可以直接调用
      • 值:函数定义(对象)
    • imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有
    //赋值都是自右向左,所以b是未经声明的变量,归window所有
    function test() {
      var a = b = 123
    }
    test()
    console.log(window.b) //123
    console.log(window.a) //undefined
    
    • 一切声明的全局变量,全是window的属性

    预编译

    • 在全局代码执行前,js引擎会创建一个栈来存储管理所有的执行上下文对象
    • 预编译发生在函数执行的前一刻
    function fn(a) {
      console.log(a) //function a() {}
      var a = 123
      console.log(a) //123  此时变量已经提升,a会被新赋值为123
      function a() {}
      console.log(a) //123 function a() {}已经被提升
      var b = function() {}
      console.log(b) //function b() {} var b已经被提升,b被新赋值为function
      function d() {} 
    }
    fn(1)
    
    • 预编译过程中做的事情:
      1.创建AO(Activation Object)(执行期上下文)
      2.找形参和变量声明,将变量和形参名作为AO属性名,值为undefined
      AO{
      a :undefined
      b :undefined
      }
      3.将实参和形参相统一
      AO{
      a :1
      b :undefined
      }
      4.找函数体内的函数声明
      AO{
      a :function a() {}
      b :undefined
      d :function d() {}
      }
      以上这些都是预编译之前做的事情,所以第一次打印a是个function,后期赋值操作是在编译时期做的,要分清。

    例子1

    function test(a,b) {
      console.log(a) //1
      c = 0
      var c
      a = 3
      b = 2
      console.log(b) //2
      function b() {}
      function d() {}
      console.log(b) //2
    }
    // test(1)
    // AO {                  
    //   a : undefined,
    //   b : undefined,
    //   c : undefined
    // }
    // -->
    // AO {
    //   a : 1,
    //   b : function,
    //   c : undefined,
    //   d : function
    // }
    // 到执行的时候:
    // AO {
    //   a : 3,
    //   b : 2,
    //   c : 0,
    //   d : function
    // }
    

    例子2

    function test() {
      console.log(a) //function
      console.log(b) //undefined
      var b = 234
      console.log(b) //234
      a = 123
      console.log(a) //123
      function a() {}
      var a
      b = 234
      var b = function() {}
      console.log(a) //123
      console.log(b) //function
    }
    test(1)
    // 预执行:
    // AO {
    //   a : undefined,
    //   b : undefined
    // }
    // -->
    // AO {
    //   a : 1,
    //   b : undefined
    // }
    // -->
    // AO {
    //   a : function
    //   b : undefined
    // }
    

    注:

    • 在全局声明时与在函数体声明的原理一样,但是少了实参与形参相统一的步骤。
    • 函数体生成的是AO对象,而全局生成的是GO对象(Global Object)(GO === window)。
    console.log(test) //function
    function test(test) {
      console.log(test) //function
      var test = 234
      console.log(test) //234
      function test() {}
    }
    
    • 自己作用域内有自己的变量先寻自己的(就近原则)
    function fn() {
      console.log(global) //undefined
      global = 200
      console.log(global) // 200
      var global = 300
    }
    fn()
    var global
    // GO {
    //   global : 100
    // }
    // AO {
    //   global : undefined
    // }
    // -->
    // AO {
    //   global : 200
    // }
    
    • 预编译时是不会看条件判断等语句,依然会变量声明提升
    function test() {
      console.log(b) //undefined
      if(a) {
        var b = 100
      }
      console.log(b) //undefined
      console.log(c) //234
    }
    var a
    test()
    a = 10
    console.log(c) //234
    

    相关文章

      网友评论

          本文标题:JavaScript预编译

          本文链接:https://www.haomeiwen.com/subject/bglaqltx.html