三行代码和你一起理解JavaScript预解析
作者:互联网
一、学习收获
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预解析就是先对函数声明和变量声明进行提升(提升完之后,在逐行执行代码)
- 变量声明提升会提升声明,但不提升赋值
- 函数声明提升优先于变量声明提升(注意这里不是函数表达式哈)
- 函数声明和函数表达式之间最重要的区别是它们的名称标识符的位置(function是声明第一个词就是函数声明,否则就是函数表达式)
四、【重要】再看这三行代码(顺序不一样了哦)
我们知道了什么是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