【转】if语句对函数声明影响

这其实是个历史遗留问题……

以前在ES5的时候,规范规定函数只能在顶层作用域和函数作用域之中声明,不能在块级作用域声明。所以,类似这样的语句其实都是非法的:

if (true) {
    function f() {}
}

但是实际上各大浏览器出于兼容性的考虑,都没有遵守这个规范。

到了现在ES6的年代,规范规定了块级作用域的存在,函数就可以在块级作用域中定义了。
但其实事情并没有这么简单,因为这样的话,函数的定义行为就和以前不兼容了,为了保证和以前的兼容性,ES6在附录B里面规定,浏览器的实现可以不遵守上面的规定,有自己的行为方式


在ES6的浏览器中,它们的行为实际上是这样的:

  1. 允许块级作用域中定义函数
  2. 函数声明实际上将会类似于使用var声明的函数表达式,函数名将会提升至当前函数作用域顶
  3. 同时函数声明也会保持在块级作用域中的提升行为

对于你的第一个代码,如果说你仔细看看它到底报的是什么错,你会发现,错误是这样的: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;
    }
}

第二段代码就不必说了吧。

文章来源:
if语句 对函数声明影响

此条目发表在JavaScript分类目录。将固定链接加入收藏夹。

发表评论

邮箱地址不会被公开。 必填项已用*标注