关于js的函数提升问题

在浏览器和html页面都运行了这几句代码
clipboard.png
js预解析是会把所有声明都提前吗,不管前面的是true还是false,还是前面是true才可以?如果改成true,也不会报错,不太明白,请教各位大神。

阅读 4.1k
5 个回答

所有的变量的声明都会提前的 提到当前作用域的顶端
可以理解为

var func;
if(false){
    func = function(){
        console.log(123);
    }
}

声明提升 但是 false 没有走赋值语句 所以 func 处于声明未赋值的状态 所以 not a function
如果没有声明的话 会报 func is not defined
我理解的是这样的 不对勿喷

es5没有块级作用域,严格模式下不能在if里定义function;非严格模式,会按照浏览器的具体实现方式进行纠错(不同浏览器表现不一样,尤其是非现代浏览器),不符合es5规范中的函数提升,并不会提升到当前作用域开头,实际操作中也不推荐把函数以声明的方式定义到if里。

首先 ECMAScript ,不得在非函数的代码块中声明函数,上述写法按照语言规范就是错的,但是各大浏览器又能够运行,这和你理解的变量提升一样

现在会报错是因为 es6 有了 块级作用域, 在块级作用域下声明函数,函数声明类似于var,函数声明还会提升到所在的块级作用域的头部,所以上述代码就等同于

    var func = undefined
    if(false){
        func = function(){}
    }
    func()

这也是为什么下面代码也会报错

    function func(){}
    (function(){
        if(false){ function func(){} }
        func() // Uncaught TypeError: func is not a function
    }())
    
    //因为上述代码等同于下面
    function func(){}
     (function(){
        var func = undefined
        if(false){ func = function(){} }
        func()
    }())

总之就是不要写不规范的代码,在块级作用域下用声明函数最好用函数表达式写法

至于报错是因为你的浏览器版本已经支持es6,你可以在老的版本上试试,或者在老的node版本里,这种写法就不会报错

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题