javascript - if语句 对函数声明影响
滿天的星座
滿天的星座 2017-06-12 09:27:40
0
3
709
console.log(e());//error

if(true){
    function e() {
        return 10;
    }
}
if(true){

    function e() {
        return 10;
    }
}
console.log(e());//10

如果函数声明提升只提升到了if作用域内,那么以上又是什么原因呢?(chrome58测试) 为何外部又能访问if的作用域内的函数? 求大神解答

滿天的星座
滿天的星座

全部回复(3)
伊谢尔伦

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

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

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

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

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


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

  1. 允许块级作用域中定义函数

  2. 函数声明实际上将会类似于使用var声明的函数表达式,函数名将会提升至当前函数作用域顶

  3. 同时函数声明也会保持在块级作用域中的提升行为

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

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

滿天的星座

if 语句内函数申明不会被提升,和函数表达式一样,所以第一个是语法错误,第二个会输出10

学霸

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
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板