• js预编译


    我们都知道js执行遵循两个规则

    1.函数声明整体提升

    2.变量 声明提升

    其实还有一点最重要的就是预编译,预编译往往发生在函数执行前,了解预编译,对我们理解函数执行非常关键。

    预编译的前奏

    1.imply global暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局属性所有。

    2.一切声明的全局变量,全是window的属性。

    下面就先看几个例子吧

    例1 function fn(a){

      console.log(a);

      var a = 123;

           console.log(a);

      function a(){};

        console.log(a);

      var b = function(){};//这是函数表达式,不是函数声明(var b属于变量声明)

      console.log(b);

      function d(){}

    }

    fn(1);

    1.创建AO对象

    AO{

    }

    2.查找函数形参及函数内变量声明,形参名及变量名作为AO对象的属性,值为undefined 

    AO{

      a:undefined;

      b : undefined;

    }

    3. 实参形参相统一,实参值赋给形参 (即把实参的值赋给形参,并不执行函数内的赋值)

    AO{

      a:1;

      b : undefined;

    }

    4. 查找函数声明,函数名作为AO对象的属性,值为函数体

    AO{ 

        a:function a(){};

      b : undefined;

      d : function d(){};

    }

    全部执行后

    AO{ 

        a:123;

      b : function (){};

      d : function d(){};

    }

    函数执行结果

     function fn(a){

      console.log(a);  //function a(){}

      var a = 123;

           console.log(a); //123

      function a(){};

        console.log(a); //123

      var b = function(){};//这是函数表达式,不是函数声明(var b属于变量声明)

      console.log(b); // function (){};

      function d(){}

    }

    fn(1);

    例2 function test(a,b){

      console.log(a);

      c = 0;

      var c;

      a = 3; 

      b = 2;

      console.log(b);

      function b(){};

      function d(){};

      console.log(b);

    }

    test(1);

    1.创建AO对象

    AO{

    }

    2.查找函数内的形参和变量声明,并将形参和变量声明作为AO对象的值,值为undefined

    AO{

      a : undefined;

      b : undefined;

      c : undefined;

    }

    3.形参实参相统一,实参的值赋给形参

    AO{

      a : 1;

      b : undefined;

      c : undefined;

    }

    4.查找函数声明,函数名为AO对象的属性,值为函数体

    AO{

      a : 1;

      b : function b(){};

      c : undefined;

      d : function d(){}

    }

    全部执行后

    AO{ 

        a:1->3;

      b : 2;

      c : 0;

      d : function d(){};

    }

    函数执行结果

     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);

    例3 function test(a,b){

      console.log(a);

      console.log(b);

      var b =234;

      console.log(b);

      a=123;

      console.log(a);

      function a(){};

      var a;

      b = 234;

      var b = function(){}

      console.log(a);

      console.log(b);

    }

    test(1);

    1. 创建AO对象

    AO{

    }

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

    AO{

      a : undefined;

      b : undefined;

    }

    3.将形参和实参相统一,实参值赋给形参

    AO{

      a : 1;

      b : undefined;

    }

    4. 查找函数声明,函数名作为AO对象的属性,值为函数体

    AO{

      a : function a(){};

      b : undefined;

    }

    执行结果

     function test(a,b){

      console.log(a); //function a(){}

      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);

    预编译不只发生在函数里,还发生在全局里,这时候回身构成一个GO(Global Object //window Object)

    例4

    console.log(test);

    function test(test){

      console.log(test);

      var test =234;

      console.log(test);

      function test(){

      }

    }

    test(1);

    var test= 123;

    1.先创建一个GO

    GO{

    }

    2.查找全局的变量声明

    GO{

      test : undefined;

    }

    4.查找函数声明

    GO{

      test :  function test(test){

                  console.log(test);

          var test =234;

          console.log(test);

          function test(){

            }

          }

        }

    1.先创建一个AO

    AO{

    }

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

    AO{

      test : undefined;

    }

    3.将形参和实参相统一,实参值赋给形参

    AO{

      test : 1;

    }

    4. 查找函数声明,函数名作为AO对象的属性,值为函数体

    AO{

     test : function test(){

        };

    }

    例5

    global = 100;

    function fn(){

      console.log(global);

      global = 200;

      console.log(global);

      var global = 300;

    }

    fn();

    var global;

    1.GO{

      global : 100;

    }

    2.AO{

      global : undefined;

    }

    执行结果

    global = 100;

    function fn(){

      console.log(global);  //undefined

      global = 200;

      console.log(global); //200

      var global = 300; 

    }

    fn();

    var global;

    例6 

    function test(){

      console.log(b);

        if(a){

       var  b  = 180;

      }

      c = 234;

      console.log(c)

    }

    var a;

    test();

    a = 10;

    console.log(c);

    1.GO{

      a : undefined;

      test :function test(){

          console.log(b);

            if(a){

           var  b  = 180;

             }

          c = 234;

          console.log(c)

          }

        }

    2.AO{

      B:undefined;

    }

    执行结果

    function test(){

      console.log(b); //undefined

      if(a){

       var b = 180;

      }

      c = 234;

      console.log(c); //234

    }

    var a;

    test();

    a = 10;

    重要的事,说多少遍都不算多哈,最后总结:

    预编译(函数执行前)※ 
    1. 创建AO对象(Active Object -- 执行上下文) 
    2. 查找函数形参及函数内变量声明,形参名及变量名作为AO对象的属性,值为undefined 
    3. 实参形参相统一,实参值赋给形参 
    4. 查找函数声明,函数名作为AO对象的属性,值为函数引用

    预编译(脚本代码块script执行前) 
    1. 查找全局变量声明(包括隐式全局变量声明,省略var声明),变量名作全局对象的属性,值为undefined 
    3. 查找函数声明,函数名作为全局对象的属性,值为函数引用

  • 相关阅读:
    Springboot默认配置文件application.properties的常见配置属性
    Springboot基础核心
    这样统计代码执行耗时,才足够优雅!
    什么原因才导致 select * 效率低下的?
    建立apk定时自动打包系统第三篇——代码自动更新、APP自动打包系统
    [LeetCode] 543. 二叉树的直径
    Mybatis源码分析(一)
    Dockerfile创建docker
    JavaScript浅析
    mac os下 vmware Fusion Linux虚拟机配置静态ip无法上网问题
  • 原文地址:https://www.cnblogs.com/xuniannian/p/8081691.html
Copyright © 2020-2023  润新知