预编译

• 我们在书写js代码的时候,会发现两点和c/c++语言不同的地方。第一个是当我们在后面定义了一个函数之后,我们在定义函数之前使用这个函数也是可以的。第二个是我们在后面声明的一个变量,但是在前面调用这个变量的时候并不会报错而是undefiend。

这两点不同在js中被称为函数声明提升变量声明提升,函数声明提升是一种整体提升,它会把函数声明和函数体一起提升到前面。变量声明提升则是一种局部提升,它仅仅将变量的声明提前了,但是并没有将赋值也一起提前。

那么为什么会出现这种提升的现象呢?

这是因为js运行的时候有一个阶段叫做预编译阶段,而我们的声明提升现象都是发生在预编译的时候哟~

 

预编译

• js运行三部曲

1.语法分析

2.预编译

3.解释执行

语法分析:js引擎在解析js代码之前,会先通篇扫描一下,找出低级的语法错误,比如写错大括号之类的。

编译执行:我们前面提到js是一种解释型语言,编译一行执行一行,当语法分析没有问题,并且已经完成预编译阶段之后,就开始解释执行代码。

这里我们着重介绍预编译。

预编译前奏

在介绍预编译之前,我们有两个重要概念需要掌握。

1.imply global 暗示全局变量

如果任何变量未经声明就赋值使用,此变量就会为全局对象window所有,并且成为window对象的一个属性。

或者

2.一切声明的全局变量,都是window的属性。

• 这样看不论全局变量有没有声明,似乎都会成为全局对象上的属性,那么两者之间有什么区别呢?

区别在于:经过声明的全局变量不能通过delete操作来删除,但是未经声明的全局变量可以被删除。

正是这一种特性,导致es5有一种弊端,我们总会在无形中声明一些全局变量。

这段代码的原意是:在函数体中声明两个变量a、b,然后初始化a、b都是0。但是我们这么写之后,a经过了声明,但是b却没有声明,这时候b就会成为一个全局变量。

了解这两点之后,我们正式介绍一下预编译的过程。

 

预编译的过程我总结为以下四步

1.创建AO对象

2.寻找形参和变量声明,将变量和形参作为AO对象的属性名添加到对象中,值为undefined。值得注意的是,函数声明不叫变量。

3.将实参值和形参值相统一。

4.在函数体里面寻找函数声明,将函数名作为属性名,值为这个函数的函数体。

函数在执行的前一刻会产生一个上下文,这个上下文就是Activeaction Object对象,简称AO对象。

AO = {}

这个对象是空的,但是里面有一些我们看不到的却存在的隐式属性,比如this: window属性和arguments: [];属性

这个对象用来存放一些属性和方法,这些属性和方法就按照前面的四步来产生。

这里我们用这一个样例代码来简单介绍一下预编译的过程。

首先第一步,创建一个AO对象。

var AO = {};

第二步,寻找形参值和变量声明,并且将值赋为undefined。

3.将实参值和形参值相统一。这里因为属性名都已经存在了,所以直接赋值就可以了。

4.寻找函数声明,将函数体赋值给属性。

这样在编译执行之前,我们预编译阶段创建的AO对象就是这个样子了,这个时候我们再看看分别打印的值是什么。

第一个console.log a –> function () {}

第二个console.log a –> 222 因为执行了a = 222这一行代码,所以重新赋值了。

第三个console.log b –> function () {}

• var b = function () {}这种不叫做函数声明,这个函数是赋值给b变量的,b变量是声明。

这里的var b = function () {}只是声明了b变量,在第四步寻找函数声明里面并不会把b赋值成function () {},因为后面的函数并不是声明,当代码开始解释执行之后,执行到这一行之后才把b赋值成这个函数。

• 寻找变量声明的时候,不会管里面的代码到底会不会执行,执行是后面的事,这里只负责寻找所有变量。

打印第一个a的时候并不会报错而是undefined,当a没有声明的时候才会报错,因此这里a是有声明的,只是没有赋值而已,它根本不看有没有if,if的条件是不是真对寻找变量声明都没有关系。

第二步寻找形参和变量声明时候的AO对象:

以上就是我总结的预编译的知识点,希望对大家有帮助哟!~

转载于:https://my.oschina.net/u/3953786/blog/2988428

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值