JavaScript 预编译原理及经典面试题

JS 语言的特点


在深入了解 JavaScript 的预编译之前,不得不先来回忆一下 JS 语言的特点:

  1. 解释型语言: 区别于编译型语言,逐行编译,就是编译一行,执行一行,而且对速度要求并不是太高;
  2. JS 引擎是单线程的;
  3. JS 符合 ECMA 标准;
  4. JS 执行队列类似于轮转时间片。

JS 运行三部曲


在这里,最重要的就是第一点:解释型语言的运行过程。 JS 运行有三部曲:

  1. 语法分析:很简单,就是通篇扫描一下有没有低级语法(语义)错误;
  2. 预编译: 简单地说就是在内存中开辟了一些空间,存放一些变量与函数;
  3. 解释执行:解释一行,执行一行。

JS 预编译实例


下面正式进入预编译的介绍,看例子为什么控制台可以打印出 ‘a’

	<script type="text/javascript">
		test();
		function test() {
			console.log('a');
		}
	</script>

如上边示例,因为有预编译的存在,test() 的调用虽然在声明之前,函数也可以执行。这是为什么呢?引出 预编译前奏 这个概念:

预编译前奏:

  1. imply global 暗示全局变量:即任何变量,如果变量未经声明就赋值,此变量就为全局对象所有;
eg: a = 123;
eg: var a = b = 123;
  1. 一切声明的全局变量,全是 window 的属性。
eg: var a = 123;

下图为一个实例,变量 a 虽然声明了,但不是全局变量,所以不能在函数体外访问到,但是变量 b 满足预编译前奏的第一点,未经声明就被赋值,此变量为全局对象所有,所以可以访问到。
在这里插入图片描述
知道了预编译前奏的概念,那么我们的理解就已经深入了一半了,顺着脉络继续。预编译前奏生成 GO(Global Object)对象,之后如果有函数就进行预编译,预编译四部曲如下:

预编译四部曲:

  1. 创建 AO 对象(Activation Object 俗称执行期上下文);
  2. 找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined;
  3. 将实参值和形参统一;
  4. 在函数体里面找函数声明,值赋予函数体。

通过简单的实例来认识一下 GO 与 AO 的结合:预编译前奏时,生成 window.b = 10;①预编译时创建 AO 对象;②将变量声明 a 放入 AO,值为 undefined;③传入参数,使得实参形参相统一,本例中没有形参;④如果函数体里还有函数声明,值赋予函数体,但是本例中没有。
最终,函数会打印出 undefined 。
在这里插入图片描述
再来一个例子,跟着我们前边的节奏来分析,先写下 GO 对象,再找 AO 对象。

	<script type="text/javascript">

		global = 100;
		function fn() {
			console.log(global);
			global = 200;
			console.log(global);
			var global = 300;
		}
		fn();
		var global;

	</script>

大家先来分析一下分别会输出什么呢?

在这里插入图片描述
我们来分析一下,global 未经声明就赋值,生成 GO 对象 global = 100;在执行到 fn() 的前一刻进行预编译,生成 AO 对象,其中只有 global,值为undefined,之后既没有实参的传入,也没有函数声明,那么第15行就打印 undefined了,经过16行之后,undefined 被修改为200 。所以两个答案分别是 undefined 和 200,你答对了吗?

百度2013面试题:

题目一:
在这里插入图片描述
因为在函数 bar 最顶端return foo,那我们直接看到 AO 的第四部:返回函数声明,那么程序会打印 function foo()。

题目二:
在这里插入图片描述
这题和上一个类似,因为函数的最后返回 foo,而 foo 在上边被赋值过,那么 foo 一定为该值咯。
看完之后我们发现,其实预编译也并不难,再梳理一下:

总结


预编译前奏:生成 GO 对象,有两个规则;
预编译四部曲:
1.创建 AO 对象
2. 找形参和变量声明,将变量和形参名作为 AO 属性名,值为 undefined;
3. 将实参值和形参统一;
4. 在函数体里面找函数声明,值赋予函数体。

底层基础决定上层建筑,这是不变的真理,深究原理绝对是没错的!

说在最后的话:编写实属不易,若喜欢或者对你有帮助记得点赞+关注或者收藏哦~

  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值