1、什么是JavaScript预解析?
2、变量声明提升和函数声明提升的特点?
3、函数声明提升优先?还是变量声明提升优先?
4、重复声明的变量是否会执行?
请问以下三行代码中,打印的结果是?
var a = 10 function a() {} console.log(a) // 这里打印的结果是?
如果对JavaScript预解析没有接触过,或者不清楚变量声明提升和函数声明提升的相关概念,很可能会得出这样的结论,以上代码打印结果为:function a() {}
,但是最终的打印结果是:10
。为什么打印10
而不是function a() {}
呢?这里就需要JavaScript预解析的机制了。
JavaScript引擎会在代码执行前对JavaScript代码进行预解析(预编译),所谓的预解析其实就是把代码中用var声明(定义)的变量和函数体(例如:function(){}
)进行提前的声明提升。
如下代码:
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
如下代码:
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 是声明中 的第一个词,那么就是一个函数声明,否则就是一个函数表达式。
我们知道了什么是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、重复声明的变量在执行过程中会被忽略掉 ,不会执行。
不忘初心,用我的分享能够让你有所收获,能够帮助到你,这就我我最大的快乐!祝好,加油!~