JS中的预编译的个人理解

129 阅读3分钟

何为预编译?

解释何为“预编译”之前先说说JS,众所周知JavaScript是解释型语言,何为解释型语言?也就是编译一行,执行一行。那又从何而来的预编译呢?

先说说JS运行的三个步骤

  1. 语法分析

  2. 预编译

  3. 解释执行

    ~~语法分析就是字面上的意思,就是检查你的代码有没有什么低级的语法错误,如果有明显的语法错误,就直接报错不执行所有的代码

    ~~预编译就是在编译内容之前对中的内容进行处理,也就是进行预处理。

    ~~解释执行顾名思义就是执行代码了

具体想要弄清楚预编译怎么回事,我们先用一个小实例看看

 var a = 123;
 console.log(a);//123

这个时候输出的值为123

 console.log(a);//undefined
 var a = 123;

刚刚我们把这两行代码前后调换了位置,得到的结果却是天壤之别,输出的值为undefined。

为何输出的是“undefined”而不是123或者报错呢?
之所以不是输出123,因为定义的变量a在console.log(a)的后面,按着Js解释型语言的特点,解释一行执行一行,console.log(a)便无法检测到a的值,那为何没有报错呢?
这就涉及到我们今天的主角了--“预编译”,正是它的原因我们这段代码在浏览器显示没有报错,这就是预编译的原因

那么我们再深度剖析何为预编译,即预编译的步骤:
初步理解就是把函数声明(function(){})整体提升最前方,变量声明(例:var a)也提升最前方。
此时我们再看之前举出的例子

console.log(a);
var a = 123;

===》预编译的过程就是把全局变量var a提升最前方,就避免了报错

var a
console.log(a);
 a = 123;

这种方法简单是简单,但遇见了复杂的代码将无从下手
下面将描述函数中真正正规对待任何函数都有作用的预编译

第一步:
创建AO(ActivationObject)活跃对象:
AO对象用来放置函数中的变量,此时的AO对象没有值

    AO = {
        
    }

第二步:
找形参和变量声明 将变量和形参作为AO对象的属性名 值为underfined 例:

    AO = {
        a:underfined
        b:underfined
    }

第三步:
将实参值和形参统一
例:

    AO = {
        a:1;
        b:underfined
    }

第四步:
在函数体里面找函数声明,值赋予函数体
例:

    AO = {
		a : function a(){},
		b : undefined,
		d :function d(){}
		}

下面我们把这四个步骤用一个具体的例子带入进去

    var a = 1;
    console.log(a);// => 1
    function test(a) {
        console.log(a);// =>function a(){}
        var a = 123;
        console.log(a);// => 123
        function a() {}
        console.log(a);// => 123
        var b = function() {}
        console.log(b);// => function()
        function d() {}
    }
    var c = function (){
        console.log("6666");
    }
    console.log(c);// => function(){console.log("6666")}
    test(2);

分析:
先找出GO全局对象GO(Global Object)全局变量

GO = {
    a : 1
    c : function(){...}
    test:function(a){...}
}

在test()之前发生预编译
预编译第一步:

 AO = {
        
    }

预编译第二步:

 AO = {
        a:undefined,
        b:undefined,
    }

预编译第三步:

 AO = {
            a:2,
            b:undefined,
        }

预编译第四步:

AO = {
        a:function a() {},
        b:undefined
        d:function d() {}
    }

预编译完成

预编译小结

1.函数声明整体提升 2.变量 声明提升 3.预编译发生在函数执行前的一刻 4.imply global 即任何变量,如果未经声明就赋值,则此变量就位全局变量所有。(例如:a = 7)