在这个例子中它应该输出什么?输出的结果是6。闭包
这个例子中它又该输出什么?输出的结果是a(),也就是输出了函数指针a。函数
这虽然是个变量和函数提高的问题,可是这二者究竟是怎么提高的?spa
var a=1; var b=2;
这是否是声明了变量就立马接着给声明的变量赋值了?指针
js解析这个代码时,它其实是按照以下方式解析的code
var a; var b; a=1; b=2;
也就是js会先把全部变量都声明好了以后,而后才进行赋值,并非声明一个变量就赋值,再声明一个再赋值。js所谓变量提高,提高就是为了事先声明变量。ip
上图中左边的例子,js解析时候是按照按照右边的代码解析的。js会把全部变量都集中提高到做用域顶部事先声明好,可是它赋值就就并非像变量声明那样集中着一个个挨着赋值。本来书写赋值时写在哪里,那么js解析运行到那一行以后才会进行赋值,尚未运行到的就不会事先赋值。也就是变量会事先声明,可是变量不会事先赋值。作用域
在做用域中,无论变量和函数写在什么位置,全部变量会被总体提高到做用域顶部,全部函数也会被总体提高到做用域顶部,可是函数总体在变量总体的后面。it
从这个例子中能够看到,变量和函数都总体提高后,函数总体在变量的后面。变量提高以后,但其赋值仍是留在本来的位置等js运行到了以后动态赋值,而函数提高以后直接至关于在代码里抽空了。class
在这个更复杂一点的例子中,变量和函数提高后,js实际上就把它转变为了右边的代码在运行。变量
搞明白这个例子也就搞懂了做用域中变量和函数是怎么提高的。
回到开头的两个问题
它们各自被js转换后如上
一个思考题,这个例子该输出什么?
“提高”的本质就是为了事先声明变量和函数,固然函数只有声明式函数才会被提高,字面量函数不会被提高。这种提高就是存在于做用域中,包括全局做用域、函数做用域(闭包造成的做用域也是个函数做用域),总之都是在做用域中声明变量和函数时,会提高到做用域顶部,进行事先声明。