编程语言
首页 > 编程语言> > 三行代码和你一起理解JavaScript预解析

三行代码和你一起理解JavaScript预解析

作者:互联网

千库网_扁平商务办公信息技术互联网智能科技矢量_插画编号91725.jpg

一、学习收获

1、什么是JavaScript预解析?

2、变量声明提升和函数声明提升的特点?

3、函数声明提升优先?还是变量声明提升优先?

4、重复声明的变量是否会执行?

二、先看这三行代码

请问以下三行代码中,打印的结果是?

var a = 10
function a() {}
console.log(a) // 这里打印的结果是?
 

如果对JavaScript预解析没有接触过,或者不清楚变量声明提升和函数声明提升的相关概念,很可能会得出这样的结论,以上代码打印结果为:function a() {},但是最终的打印结果是:10。为什么打印10而不是function a() {}呢?这里就需要JavaScript预解析的机制了。

三、JavaScript预解析

JavaScript引擎会在代码执行前对JavaScript代码进行预解析(预编译),所谓的预解析其实就是把代码中用var声明(定义)的变量和函数体(例如:function(){})进行提前的声明提升。

1、变量声明提升

如下代码:

var a = 10
console.log(a) 

var a = 10;这样的变量声明,会被分解成两个独立的步骤:

// 1、对变量的声明进行提升
var a
// 2、对变量a进行赋值
a = 10
console.log(a) 

以上就是其实就是JavaScript引擎对JavaScript代码预解析的过程,也是变量声明提升的过程,预解析完毕之后,JavaScript引擎才会按照预解析后的代码逐行进行执行,很显然上面代码打印的最终结果是 10

注意console.log(a)不会参与到预解析过程中,所以console.log(a)不会提升,预解析的过程只是涉及到变量声明提升和函数声明提升。

通过上面的代码,我们可以得出一个结论:变量声明提升,只提升声明,而不会提升赋值

// 1、变量声明提升
var a
// 2、赋值不会提升
a = 10

2、函数声明提升

如下代码:

var a = 10
function a(){}
console.log(a) 

function a(){}这样的函数声明,会把函数声明提升到当前作用域的前面,注意是最前面

对,你没有看错,是最前面,所以这里也有一个结论:函数声明提升优先于变量声明提升

提升后如下所示:

// 1、函数声明提升到当前作用域最前面
function a(){}
// 2、变量声明提升
var a
// 3、变量赋值(不会提升)
a = 10
console.log(a) 

所以根据以上的预解析,然后再逐行执行代码,所以最后结果打印为10(到这里就解释了为什么一开始上面为什么打印10而不是function a() {}的问题了)。

注意、注意、注意:函数表达式和函声明是有区别的,函数表达式提升不会跟函数声明提升一样,它跟变量声明提升是一样的(只提升声明,不会提升赋值)

var a = function () {} // 这是函数表达式,不是函数声明

区分函数声明和表达式最简单的方法是看 function 关键字出现在声明中的位 置(不仅仅是一行代码,而是整个声明中的位置),如果 function 是声明中 的第一个词,那么就是一个函数声明,否则就是一个函数表达式。

3、 小结

四、【重要】再看这三行代码(顺序不一样了哦)

我们知道了什么是JavaScript预解析(变量声明提升和函数声明 提升),可以再看如下代码,请说出打印的结果是?

console.log(a) 
var a = 10
function a(){}

思考……,按照上面的预解析,很多人得出的结果是 undefined,但是实际执行代码之后 ,最终结果是function a(){}

why?

我们一起再来看看,以上三行代码预解析是怎样的,执行过程中发生了什么事情?

上述代码按照JavaScript预解析的机制,预解析代码如下所示:

function a(){} // 1、函数声明优先于变量声明提升,提升到当前作用域最前面
var a // 2、变量声明提升只提升声明,不提升赋值
console.log(a) 
a = 10  

根据以上的预解析之后的代码,很多人一致认为结果就是 undefined(因为 var a 的默认值是undefined,所以打印的结果是 undefined),但是当我们执行以上的预解析代码之后,最终结果仍然是 function a(){}

所以肯定是在执行过程中发生了一些事情,并不是预编译的机制出现问题了。

代码执行过程分析(需要跟着我的思路走哦):

function a(){} // 1、首先这里是不是声明(定义)了a,a是一个函数? 你的肯定:是的。
var a // 2、在这里是不是又重新声明了一次a?你的肯定:是的。【重要】注意了:重复的声明会被忽略掉,不会执行。所以这个 var a不会执行。
console.log(a) // 3、由于 var a 不会执行,所以打印的结果是 function a(){}
a = 10  

至此,以上我们就清晰的理解了,为什么以下这三行代码执行的结果是 function a(){}

console.log(a) // function a(){}
var a = 10
function a(){}

五、总结

1、JavaScript预解析就是先对函数声明和变量声明进行提升(提升完之后,在逐行执行代码);

2、变量声明提升会提升声明,但不提升赋值;

3、函数声明提升优先于变量声明提升;

4、重复声明的变量在执行过程中会被忽略掉 ,不会执行。

不忘初心,用我的分享能够让你有所收获,能够帮助到你,这就我我最大的快乐!祝好,加油!~

标签:function,函数,JavaScript,三行,var,解析,声明,变量,提升
来源: https://blog.csdn.net/it_cgq/article/details/120873725