28

打一个小广告,作者本人开发的一个集合优质编程教程与视频的网站(包含大量慕课网体系课与实战课),感兴趣的同学可以看一下,青苹网 www.qingp.net


问题

clipboard.png

在这个例子中它应该输出什么?输出的结果是6。

clipboard.png

这个例子中它又该输出什么?输出的结果是a(),也就是输出了函数指针a。

这虽然是个变量和函数提升的问题,但是这两者到底是怎么提升的?

js是怎么创建变量的

var a=1;
var b=2;

这是不是声明了变量就立马接着给声明的变量赋值了?

js解析这个代码时,它实际上是按照如下方式解析的

var a;
var b;
a=1;
b=2;

也就是js会先把所有变量都声明好了之后,然后才进行赋值,并不是声明一个变量就赋值,再声明一个再赋值。js所谓变量提升,提升就是为了事先声明变量。

clipboard.png

上图中左边的例子,js解析时候是按照按照右边的代码解析的。js会把所有变量都集中提升到作用域顶部事先声明好,但是它赋值就就并不是像变量声明那样集中着一个个挨着赋值。原本书写赋值时写在哪里,那么js解析运行到那一行之后才会进行赋值,还没有运行到的就不会事先赋值。也就是变量会事先声明,但是变量不会事先赋值。

函数和变量都提升时,谁提到前面谁提到后面

在作用域中,不管变量和函数写在什么位置,所有变量会被整体提升到作用域顶部,所有函数也会被整体提升到作用域顶部,但是函数整体在变量整体的后面。

clipboard.png

从这个例子中可以看到,变量和函数都整体提升后,函数整体在变量的后面。变量提升之后,但其赋值还是留在原本的位置等js运行到了之后动态赋值,而函数提升之后直接相当于在代码里抽空了。

clipboard.png

在这个更复杂一点的例子中,变量和函数提升后,js实际上就把它转变为了右边的代码在运行。

搞明白这个例子也就搞懂了作用域中变量和函数是怎么提升的。

结语

回到开头的两个问题

clipboard.png

它们各自被js转换后如上

clipboard.png

一个思考题,这个例子该输出什么?

“提升”的本质就是为了事先声明变量和函数,当然函数只有声明式函数才会被提升,字面量函数不会被提升。这种提升就是存在于作用域中,包括全局作用域、函数作用域(闭包形成的作用域也是个函数作用域),总之都是在作用域中声明变量和函数时,会提升到作用域顶部,进行事先声明。


hebe700
729 声望15 粉丝

d