#我的21天#《你不知道的javascript》- D4

前端之家收集整理的这篇文章主要介绍了#我的21天#《你不知道的javascript》- D4前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

提升

函数作用域和块级作用域的行为是一样的,可以总结为:任何声明在某个作用域内的变量,都将附属于这个作用域。

先有鸡还是先有蛋

看一个栗子

很多人会认为结果是undefined,理由是第三行的变量定义会覆盖掉a原来的值,但是真正的结果是2.
在看另外一个栗子

你可能会认为这里的值是2或者抛出错误,但是这里的值时undefined

编译器再度来袭

为了搞清楚到达是先有鸡还是先有蛋,我们需要回顾一下这个问题。
在第一章节我们讲解了关于编译器的内容,引擎牛仔解释javascript代码之前首先对其进行编译,而编译阶段中的工作就包含了找到所有的声明,并用合适的作用域将他们关联起来。
所以我们可以预想到的是,引擎在编译阶段,会将所有的变量声明和函数声明提前进行处理,就像上面的例子var a = 2,这里看似是一个声明,但是在引擎看来他是var a;a = 2这两个声明的结合体。其中var a;是在编译阶段进行的,而第二个声明会留在原地等待执行阶段。
上面第一段代码可以理解为

类似的第二段代码也是按照如下的流程进行处理的

这也就不难解释上面的运行结果为什么是undefined了。
类似变量声明,函数声明也会被相应的在编译阶段被处理(提升),但是对于函数表达式来说却不会被提升。
看一段代码

上面的代码中,根据我们结合上诉的理解,其实它的执行流程如下:

其中,由于函数表达式是不会在编译阶段被提升的,所以上诉代码中第二行报了TypeError错误,而不是RefferenceError。这是因为,foo变量声明被提前,第二行foo( )对foo的RHS查找找到了foo这个变量,但是这个变量此时还没有指向函数,所以也就是会报TypeError

函数优先

值得注意的一个细节是,函数会先于变量提前。应该尽量避免在块内部声明函数。要注意避免重复声明,特别是当普通的var声明和函数声明混合子啊一起的时候,否则会引起很多危险的问题!

猜你在找的JavaScript相关文章