对于你的第一个代码,如果说你仔细看看它到底报的是什么错,你会发现,错误是这样的:Uncaught TypeError: e is not a function。 Uncaught TypeError: e is not a function。 这个错误表示,e不是函数,换句话来说,就是e这个错误表示,e不是函数,换句话来说,就是e这个变量是存在的,但它不是函数。结合我们上面提到的三条规则,很容易就能想到,实际上它运行的是这个:
console.log(e());//error
if(true){
var e = function() {
return 10;
}
}
经过变量提升之后,将会变成这样:
var e;
console.log(e());
if(true){
e = function() {
return 10;
}
}
这其实是个历史遗留问题……
以前在ES5的时候,规范规定函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。所以,类似这样的语句其实都是非法的:
但是实际上各大浏览器出于兼容性的考虑,都没有遵守这个规范。
到了现在ES6的年代,规范规定了块级作用域的存在,函数就可以在块级作用域中定义了。
但其实事情并没有这么简单,因为这样的话,函数的定义行为就和以前不兼容了,为了保证和以前的兼容性,ES6在附录B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
在ES6的浏览器中,它们的行为实际上是这样的:
允许块级作用域中定义函数
函数声明实际上将会类似于使用
var
声明的函数表达式,函数名将会提升至当前函数作用域顶同时函数声明也会保持在块级作用域中的提升行为
对于你的第一个代码,如果说你仔细看看它到底报的是什么错,你会发现,错误是这样的:
Uncaught TypeError: e is not a function
。Uncaught TypeError: e is not a function
。这个错误表示,
e
不是函数,换句话来说,就是e
这个错误表示,e
不是函数,换句话来说,就是e
这个变量是存在的,但它不是函数。结合我们上面提到的三条规则,很容易就能想到,实际上它运行的是这个:经过变量提升之后,将会变成这样:
第二段代码就不必说了吧。
if 语句内函数申明不会被提升,和函数表达式一样,所以第一个是语法错误,第二个会输出10
相当于 =>