javascript - if語句 對函數宣告影響
滿天的星座
滿天的星座 2017-06-12 09:27:40
0
3
704
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 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 語句內函數申明不會被提升,和函數表達式一樣,所以第一個是語法錯誤,第二個會輸出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
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板