Heim > Fragen und Antworten > Hauptteil
console.log(e());//error
if(true){
function e() {
return 10;
}
}
if(true){
function e() {
return 10;
}
}
console.log(e());//10
Wenn die Funktionsdeklarationsförderung nur auf den if-Bereich heraufgestuft wird, was ist dann der Grund dafür? (Chrome 58-Test) Warum kann auf Funktionen im Rahmen von if von außen zugegriffen werden?
伊谢尔伦2017-06-12 09:29:40
这其实是个历史遗留问题……
以前在ES5的时候,规范规定函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。所以,类似这样的语句其实都是非法的:
if (true) {
function f() {}
}
但是实际上各大浏览器出于兼容性的考虑,都没有遵守这个规范。
到了现在ES6的年代,规范规定了块级作用域的存在,函数就可以在块级作用域中定义了。
但其实事情并没有这么简单,因为这样的话,函数的定义行为就和以前不兼容了,为了保证和以前的兼容性,ES6在附录B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式。
在ES6的浏览器中,它们的行为实际上是这样的:
允许块级作用域中定义函数
函数声明实际上将会类似于使用var
声明的函数表达式,函数名将会提升至当前函数作用域顶
同时函数声明也会保持在块级作用域中的提升行为
对于你的第一个代码,如果说你仔细看看它到底报的是什么错,你会发现,错误是这样的:Uncaught TypeError: e is not a function
。
这个错误表示,e
不是函数,换句话来说,就是e
这个变量是存在的,但它不是函数。结合我们上面提到的三条规则,很容易就能想到,实际上它运行的是这个:
console.log(e());//error
if(true){
var e = function() {
return 10;
}
}
经过变量提升之后,将会变成这样:
var e;
console.log(e());
if(true){
e = function() {
return 10;
}
}
第二段代码就不必说了吧。
欧阳克2017-06-12 09:29:40
if(true){
function e() {
return 10;
}
}
相当于 =>
var e
//e为undefined 所以下面报错
console.log(e());//error
if(true) {
e = function() {
return 10;
}
//if内的其他语句
}
//e已经被修改为function了,所以下面的语句正常
console.log(e());//10