• js 预编译


    js 运行代码的时候分为几个步骤:语法分析 ==》预编译  ==》解释执行

    语法解析:通篇扫描代码,查看语法是否出错

    解释执行读一行 - 解释一行 - 执行一行

    预编译执行的操作:

    // 假设之前并没有定义a
    console.log(a);

    打印结果:Uncaught ReferenceError: a is not defined

    这个大家应该都知道:在变量未定义时就对变量进行访问就会报错(typeof 列外)

    再看一个例子:

    // 假设之前并没有定义变量a
    console.log(a);
    var a = 123;
    console.log(a);

    看上面代码会打印什么?会不会报错?

    打印结果:

    undefined
    123

    为什么这个没有报错:因为在预编译的时候对变量进行了提升即变量提升。 定义的变量的声明(var a ;)被提到了代码块的最前面,变量的赋值操作(a = 123)没有变化。

    所以被编译后就相当于

    // 假设之前没有定义变量a
    var a;
    console.log(a);
    a = 123;
    console.log(a);

    看下面这个例子:

    // 假设之前没有定义test
    console.log(test);
    var test = 123; 
    function test () {
    
    }
    console.log(test);

    打印结果:

    function test () {}
    123

    为什么第二行的输出的不是undefined 了?执行步骤是什么样子的?

    因为函数声明在编译的时候也会进行提升,叫做函数提升

    执行步骤:

    1、变量提升:var test; 提升到最前面。此时test = undefined;

    2、函数提升:function test () {}; 提升到最前面并覆盖var test; 的声明。所以第二行打印function test () {}; 此时test = function test () {}

    3、进行赋值操作 test = 123; 此时test = 123;

    function test (test) {
      console.log(test);  // function test(){var a = 789}
       var test = 123;
       function test () {
           var a = 789;
        };
       console.log(test) ;  // 123     
    }
    
    test(456);

    Why?

    变量提升和函数提升是如何实现的?

    预编译执行步骤

    (a) 函数内

     1、在代码定义之后执行之前生成AO(Activation Object ) 空对象{}

     2、查找函数体内的形参和变量,定义为AO的属性,赋值为undefined;

     3、将实参跟形参统一,即把实参赋值给AO[形参]

     4、查找函数里的函数声明,将函数声明赋值给AO 即 AO[函数名] = 函数

    (b) 全局

     1、在代码定义之后执行之前生成GO(Global Object ) 空对象{}

     2、查找变量,定义为GO的属性,赋值为undefined;

     3、查找函数声明,将函数声明赋值给GO 即 GO[函数名] = 函数;

    以上面的例子分析预编译过程:

    function test (test) {
       console.log(test);  // function test(){var a = 789}
        var test = 123;
        function test () {
            var a = 789;
         };
        console.log(test) ;  // 123     
     }
     
    test(456);
    
    var a = 111;

    /** 全局 **/ // 第一步:创建GO // GO{}; // 第二步:查找变量定义为GO的属性,赋值为undefined;
    // GO{
    // a: undefined
    // };
    // 第三步:将函数声明赋值给GO
    // GO{
    // a: undefined,
    // test: function test(test) {...}
    // }

    /** function test(test){...} 函数内 **/
    // 第一步: 创建AO
    // AO {}
    // 第二步: 查找形参和变量,定义为AO的属性, 赋值为undefined;
    // AO {
    // test: undefined
    // }
    // 第三步: 形参和实参统一
    // AO {
    // test: 456
    // }
    // 第四步:将函数声明给AO
    // AO {
    // test: function test() { var a = 789 }
    // }

    电脑刺绣绣花厂 http://www.szhdn.com 广州品牌设计公司https://www.houdianzi.com

    之后就是一步一步的执行代码了

    function test (test) {
       console.log(test);  // function test(){var a = 789}
        var test = 123;
        function test () {
            var a = 789;
         };
        console.log(test) ;  // 123     
     }
     
    test(456);
    
    var a = 111;
    
    // test(456); 进入到function test (test) {...} 内部
    // console.log(test); // 打印 function test(){var a = 789}
    // var test = 123; 由于 test 变量的声明已经提升,所以这句只执行 test = 123; 即AO[test] = 123
    // AO {
    //   test: 123
    // }
    // function test() {var a = 789} 已经提升
    // console.log(test) //打印 123
    // 退出function test (test) {...} 销毁AO
    // var a = 111; 由于 a 变量已经提升,这句只执行赋值 a = 111; 即 GO[a] = 111;
    // GO{
    //   a: 111,
    //   test: function test(test) {...}
    // }
    
    // 当页面销毁时销毁GO
  • 相关阅读:
    索引查找Java实现
    经典算法之折半查找
    进制转换问题
    排序算法总结之希尔排序
    自己写的栈
    排序问题Java
    画柱状图Java
    一些值得看的性能优化的文章
    理解 BFC
    canvas
  • 原文地址:https://www.cnblogs.com/qianxiaox/p/13821761.html
Copyright © 2020-2023  润新知