对于JS预编译的理解

JS代码执行过程
 我们都知道,JS语言是一种单线程解释性语言。它是一门语言,它有它自己的执行机制。来看下吧。

 1. 首先,进行语法分析,语法分析就是浏览器先通栏浏览一下整体的代码有没有少写分号、单词拼错等语法的错误
 2. JS预编译。本质是创建AO对象或GO对象,对其属性的操作。
 3. 最后解释性执行。就是一行一行的读取代码执行代码。


JS预编译(AO对象及GO对象)
  预编译简单理解就是,在代码执行前一刻发生的事情,我们要做到的就是弄清楚具体发生了哪些事情,是怎么发生的,也就是理解JS预编译的过程。


AO对象即Activation Object,指活动性对象,也叫执行期上下文,就是我们通常所说的作用域。这里指函数的局部作用域。

(执行规则如下)

 1.函数在执行前的瞬间,生成一个AO对象;
 2.看参数,形参作为AO对象的属性名,实参作为AO对象的属性值;
 3.看变量声明:变量名作为AO对象的属性名,值为undefined,如果变量名和形参重名,则不用管;
 4.看函数声明,函数名为AO对象的属性名,值为函数体,如果遇到同名(变量名或者形参名),直接覆盖(函数体去覆盖属性值)。

咱们先看看一个简单的例子。

	function test(a,b){
	    console.log(a);
	    var a=123;
	    function a(){};
	    console.log(b);
	    var b=234;
	    console.log(b);
	    function b(){};
	    console.log(a);
	    var b=function(){};
	    console.log(b);
	}
	test(1);

  首先js的执行过程会先扫描一下整体语法语句,如果存在逻辑错误或者语法错误,那么直接报错,程序停止执行,没有错误的话,开始从上到下解释一行执行一行。但是js中首先你要清楚变量声明和函数声明是会提升的。

计算机执行到test()函数时,在执行的前一刻会创建一个AO对象。

即第一步:创建AO对象 AO{};

第二步: 把形参和变量声明作为对象的属性储存到AO对象中,value为undefined即属性值为undefined;
AO {
        a: undefined // 形参a和变量声明的a一样,只需写一个
        b: undefined
    }
    
第三步:将形参和实参进行统一。
AO{
		a:1
	 	b:undefined
}

第四步:将所有的函数声明的函数名作为AO对象中的key,函数整体内容作为value,存储到AO对象中
AO{
    	a:function a(){}
    	b:function b(){}
}

然后进行代码执行,从上往下执行,预编译后执行代码:

第一条执行的是控制台打印出a的值,所以输出function a() {};
第二条语句赋值给a,则AO对象中a的值被覆盖为123;
第三条语句为声明,预编译处理过所以直接跳过;
第四条为打印出b的值function b() {};
第五条为赋值,赋值b的值为234;
第六条语句控制台打印b的值为234;
第七条为声明,预编译处理过所以直接跳过;
第八条语句控制台打印a的值为123;
第九条为赋值,赋值b的值为function () {};
第十条打印出b的值function () {};

所以输出结果应该是:
function a() {}
function b() {}
234
123
function () {}

执行效果如图:
运行结果

  需要注意的点,就是当变量名和函数名一样时,AO对象就添加一个属性,代码往后执行时,属性值会被覆盖掉的。上面的例子就已经很好的解释说明了JS预编译的过程。最最最核心的就是,预编译时AO对象的属性对应的属性值,会在后续代码执行过程中发生变化,也就是会被覆盖。


GO规则即Gobel Object,是全局对象,GO对象跟window对象是同一个对象。可以理解为window对象有两个名字 window == GO。

(执行规则如下)
 1.进入script标签,需要执行代码前的一瞬间,生成一个GO对象;
 2.看变量声明,变量名为GO对象的属性名,值为undefined;
 3.看函数声明,函数名为GO对象的属性名,值为函数体,如果遇到同名(变量名),直接覆盖(函数体去覆盖属性值)。

举个简单的例子。

	<script>
		console.log(a);
        var a = 123;
        function a () {};
        console.log(a);   
    </script>
第一步:生成GO对象 GO{}
第二步:将声明变量添加进GO对象
GO{
	a:undefined;
}
第三步:将声明函数添加进GO对象
GO{
	a:~~undefined~~  ; function a () {};//覆盖a的值
}

按顺序执行代码
第一次输出结果为:function a () {}
第二次输出结果为:123

执行结果如下图
在这里插入图片描述

以上是个人关于Js中AO及GO对象的理解,如有遗漏欢迎补充。

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值