js的预编译

2 篇文章 0 订阅

js的两大特点:解释性和单线程
解释性:翻译一行执行一行,但是在翻译之前需要经历预编译阶段,在这个阶段中将该提升的提升,该赋值的赋值,并且检查语法错误,完成之后执行代码。
所以js的预编译发生在代码执行的前一个阶段。

js预编译的步骤:
①. 创建AO对象(Activitity Object)(执行器上下文)
②. 找形参和变量声明,将变量和形参作为AO的属性名,且赋值为undefined
③. 将实参和形参统一
④. 在函数体内找函数声明,且AO对象的值赋予函数体

主要的就是要理解上面的步骤,有了上面的步骤之后,来一个测试:
example1:

function fn(a) {
	console.info(a)         // function a() {} 
	var a = 123
	console.info(a)        // 123
	function a() {}
	console.info(a)       // 123
	var b = function() {}
	console.info(b)      // function() {}
	function d() {}
}
fn(1)

1.创建AO对象

AO: {

}
  1. 找形参和变量,并且将形参和变量作为AO的属性名,且赋值为undefined
    当执行fn函数的时候,找出形参和变量,从上往下分别是: a(形参和变量a相互覆盖), b(函数表达式也是变量)
AO: {
	a: undefined,
	b: undefined
}
  1. 将实参和形参统一,此时a为fn(1)的参数1
AO: {
        	a: 1,
        	b: undefined
        }
  1. 在函数体内找函数声明,且赋值予函数体
    函数声明有函数a和函数d,所以将AO中的a替换为函数体a, 再新加属性d
AO: {
        	a: function a() {},
        	b: undefined,
        	d: function d() {}
        }

以上4步完成之后预编译也完成了,现在就是执行。

第一个console.info(a),此时AO中的a是function a() {}
第二个console.info(a),此时a已经被重新赋值为123,此时AO为,打印出123

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

第三个console.info(a),function a() {}已经被提升,不会执行,打印出123

第四个console.info(b), b被赋值为函数体function() {}, AO为,

AO: {
        	a: 123,
        	b: function() {}
        	d: function d() {}
        }

结果为function() {}

至此执行完成。

再看一个例子
example2

function test(a, b) {
	console.log(a)     // 1
	c = 0
	var c
	a = 3
	b = 2
	console.log(b) // 2
	function b() {}
	function d() {}
	console.log(b) // 2
}

  test(1)

按步骤来,,这块将不做过多的文字描述,主要看下AO的变化。

  1. 找形参和变量,赋值undefined
AO : {
         	a: undefined,
         	b: undefined,
         	c: undefined,
          }
  1. 将形参和实参统一,此时a为1
AO : {
         	a: 1,
         	b: undefined,
         	c: undefined,
          }
  1. 找函数声明,赋值函数体
AO : {
         	a: 1,
         	b: function b() {},
         	c: undefined,
         	d: function d() {}
          }

接下来浏览器会严格按照翻译一行执行一行的顺序执行。
所以依次会打印: 1, 2, 2

example3
再来一个,含有两个执行上下文(GO Global Object 全局执行上下文)和(AO)

console.log(test)
function test(test) {
	console.log(test)
	var test = 123
	console.log(test)
	function test() {}
}
test(1)

在全局存在GO

GO: {
	test:undefined -> function test(test) { .......}    // 先赋值为undefined,最后赋值为函数声明的函数体
}

在AO中

AO: {
	test: undefined -> 1 -> function test() {}    // 先赋值undefined,接着实参形参统一,最后函数声明赋值为函数体
}

所以从上到下依次打印: function test(test) { …} , function test() {}, 123

注意:有if语句的时候,不管成不成立,内部都会进行预编译。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值