• JavaScript预编译详解


    一、js运行三部曲:

    1.语法分析(通篇扫描看有没有语法错误)

    2.预编译

    3.解释执行

     

    二、预编译前奏

      1、imply global 暗示全局变量:任何变量如果未经声明就赋值,此变量为全局对象所有

        eg: a = 123;

        var a = b =123;

      2、一切声明的全局变量,全是window的属性,一切定义在全局上的变量,都归window所有(window等价于全局)

        eg:    console.log(a)   等价于  console.log(window.a);

        举个例子:

    <script>
    
    function test(){
        var a = b = 123;
    }
    
    test();
    console.log(b);
    
    </script>
    

    其结果为:123

    如果将console.log(b) 改成 console.log(a) 则会出现 “ReferenceError: a is not defined” 的错误。

    这是因为执行test()函数时,先对  b赋值,使 b=123, 然后再 var a 进行声明, 最后使a=b,

    b在未声明的时候进行赋值,所以为全局变量,可以在函数外访问,而a则是局部变量,不能再函数外访问

    三、预编译的两个规则:

      a.函数声明整体提升 :  函数声明不管位于哪里,系统总会把声明提升到逻辑的最前面,因此无论函数调用在声明前或声明后结果都一样

      b.变量   声明提升:会把变量的声明提升到函数调用前面

    举两个小例子:

    <script>

      test();

      functiont  test(){

      console.log('a');

      }

    </script>
    

     输出的结果为: a

    <script>
        console.log(a);
        var a = 123;
    </script>

    输出结果为:undefined;

    四、预编译四部曲(函数预编译时)

      通过下面例子进行讲解

    <script type="text/javascript">
        function fn(a) {
            console.log(a);
            var a = 123;
            console.log(a);
            function a() {}
            console.log(a);
            var b = function() {}
            console.log(b);
            function d() {}
        }
    
        fn(1);
    
    1.创建AO对象 (Activation object)(执行期上下文)
    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(){}
    }

    预编译完后进行执行:
        首先一句一句执行,执行第一句console.log(a);那么,会在AO对象中调取a,在AO对象中a等于function a(){},那么就输出function a(){}
      然后到达第二句
    var a = 123,var a 已经被提升了,所以不用管,直接到a = 123,所以,在AO对象中,a变成了123
      AO对象变成123后,再来进行执行第三句,console.log(a);那么,现在a等于123,那么就是输出123,
      到达第四句,第四句是函数,由于函数已经被提升了,所以没有这一步,然后再到第五句,第五句是console.(a),所以输出还是123吧
      然后再到第六句,第六句是var b = function (){},所以就要把在AO对象中的b的属性改为function(){}

      所以在第七句b的输出就是function(){},第八句直接被提升了,所以不用读了。

    结果为:
    function a(){}
    123
    123
    function (){}


    全局预编译:
    生成一个GO global object对象(等价于window)

    例:
      
    <script>
        global = 100;
        function fn(){
        console.log(global);
        global=200;
        console.log(global);
        var global=300;
    }
        fn();
        var global;
    </script>
    

     结果为:

    undefined
    200

    执行过程:首先生成GO{
    global:undefined
    }
    执行第一行:global = 100
    执行fn()时生成AO{
    global = undefined;
    }


    注意
      js不是全文编译完成再执行,而是块编译,即一个script块中预编译然后执行,再按顺序预编译下一个script块再执行
      但是此时上一个script快中的数据都是可用的了,而下一个块中的函数和变量则是不可用的。

     
  • 相关阅读:
    海量的数据的处理
    leetcode(135)分发糖果
    leetcode(130)被围绕的区域
    排序算法
    leetcode(956)最高的广告牌
    kafka的配置
    kafka命令行
    leetcode(76)最小覆盖子串
    Vue开发全解
    idea eclipse 设置代理
  • 原文地址:https://www.cnblogs.com/forever-Ys/p/10063837.html
Copyright © 2020-2023  润新知