死磕JavaScript变量和函数的预解析

Posted sauronblog

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了死磕JavaScript变量和函数的预解析相关的知识,希望对你有一定的参考价值。

预解析:在解析代码之前做一些处理

预解析做什么处理?
把变量的声明提前了----提前到当前所在的作用域的最上面
函数的声明也会被提前---提前到当前所在的作用域的最上面
 
那么我们现在开始举几个例子
1、观察下方的第一个红框中的代码,猜猜它的结果是什么?
技术图片

通过运行我们发现,代码竟然神奇的没有报错?但是输出的也不是下面赋值的1而是undefined,这到底是为什么呢?其实这就是因为js引擎的预解析将num这个变量的声明提前到作用域的最上方(num是全局变量所以提前到最外层也就是script标签内的最上方),导致代码变成了第二个红框中的代码,所以在输出num的时候num还没有被赋值导致控制台输出undefined。

 

2、观察下方的第一个红框中的代码,猜猜它的结果是什么?

技术图片

 结果是undefined,此题要注意的就是输出语句所在的函数内有一个与全局变量重名的变量num,此时要注意局部变量可不会覆盖全局变量,局部变量num由于预解析将声明放在了其作用域顶部(它的作用域就是函数f1内部所以提前到函数内容头部),此时其并没有赋值所以会输出undefined。

 

3、那么我们吧var=10”去掉又会如何呢?观察下方的第一个红框中的代码,猜猜它的结果是什么?

技术图片

结果是并不是输出 20 而是 undefined,你猜对了么?
那么为什么会输出undefined呢?就是因为js引擎会对其进行预解析,解析过程就是将变量的声明(千万要注意仅仅是声明并不包括赋值)和函数声明提前到作用域的最上方,最终变成第二个红框中的代码。

 

 4、观察下方的第一个红框中的代码,猜猜它的结果是什么?

技术图片

结果并不是输出1和2而是输出两次2,原因是经过预解析以后第一个红框中的代码变成了第二个红框中的代码,而且蓝框中的函数名字和绿框中的函数名字一模一样,所以绿框中的函数会覆盖蓝框中的函数最终导致蓝框中的函数消失,所以下方两次调用的都是绿框中的函数。怎么样,这次你猜对了么?

拓展:注意变量的名字和函数的名字也不能相同,否则同样会发生覆盖!示例如下

技术图片

 

显然结果并不是undefined,而是函数。

 

5、观察下方的代码,猜猜它的结果是什么?

技术图片

结果是
1
11
2
22
可见两个script标签中的代码并没有发生覆盖。
 
拓展:经过我个人测试,第二对script标签中代码执行的规律是如果第二对script标签中存在将要使用的变量或函数那就使用这个变量和函数,如果不存在那就去第一对script标签中查找如果存在就拿来使用。
 
6、观察下方的第一个红框中的代码,猜猜它的结果是什么?

 技术图片

答案是
9
9
9
9
9
报错
前面预解析部分没有什么特殊的,要注意绿框中的代码,不要想当然的认为连等赋值全是显式局部变量,事实上除了第一个是显式局部变量后两个都是隐式全局变量。

 

7、观察下方的第一个红框中的代码,猜猜它的结果是什么?

技术图片

 

 答案是无法运行直接报错,这是因为预解析把变量声明提前,而给f1赋值并不会提前。

 

 

 

 

以上是关于死磕JavaScript变量和函数的预解析的主要内容,如果未能解决你的问题,请参考以下文章

javascript的预解析与变量提升

JavaScript预解析

JS——变量和函数的预解析匿名函数函数传参return

js 函数 /变量/ 以及函数中形参的预解析的顺序

js之预解析

从function的定义看JavaScript的预加载