搜尋

首頁  >  問答  >  主體

javascript - 函數宣告和宣告變數同時存在,提升的規則是什麼?

我們知道宣告變數是會提升的:

var a = 1;
//上面一行相当于下面这样:
var a;
a = 1;

同時,函數宣告也是會被提升的:

foo();
function foo(){};
//上面两行相当于下面这样:
var foo;
foo = function (){};
foo()

那麼,當變數和函數宣告都有時,誰會提升到更上面呢?怎麼排序呢?比如下面這樣:

var a = 1;
foo();
function foo(){};

是這樣嗎?

var a;
var foo;
a = 1;
foo = function(){};
foo();

因為在《你不知道的JAVASCRIPT》看到這句話,有點困惑:

函數宣告和變數宣告都會被提升。但是一個值得注意的細節是,函數會先被提升,然後才是變數。函數宣告會被提升到普通變數之前。

所以說會是這樣排序嗎:

var foo;
foo = function(){};
var a;
a = 1;
foo();

求解排序規則,謝謝!

高洛峰高洛峰2795 天前607

全部回覆(3)我來回復

  • 仅有的幸福

    仅有的幸福2017-05-18 10:57:55

    這個「先提升的」說法其實有誤解的,這個只是表象而已。規範裡是不分先後的(對 V8 的實現有興趣可以看這裡)。

    var 的提升是声明跟赋值分开,function 提升則是整個提升,所以

    var a = 1;
    a();
    function a(){};

    就會變成這樣

    var a;
    function a(){};
    a = 1;
    a();

    所以就有了函數先提升的效果。

    回覆
    0
  • 巴扎黑

    巴扎黑2017-05-18 10:57:55

    首先,我們可以把它分成4塊內容

    var a ;
    a =1;
    foo();
    function foo();
    

    我們想知道提升後排序是什麼形式?
    目前已知條件是,變數宣告會提升到變數賦值之前,所以我們可以先將變數宣告放到前兩位,暫時不管其內部順序:

    var a ;
    function foo(){};
    a=1;
    foo();
    

    接下來我們來分別決定聲明和賦值模組的內部排序。
    為了進行實驗,我們將foo函數擴充,所以現在的排序為:

    var a;
    function foo(){console.log(a+1)};
    a=1;
    foo();
    

    先不要管為什麼這麼改,我們繼續實驗,實驗過程中會理解。
    為了方便理解,實驗分兩次進行。
    首先:我們對變數聲明模組進行實驗。

    var a=1;
    console.log(foo);//若输出为function foo(){}则证明函数声明位于变量声明之前;若为undefined,说明相反。
    foo();
    function foo(){console.log(a+1)};
    

    然後:我們對變數賦值模組進行實驗。

    var a=1;
    foo();//若输出为undefined1,则证明foo()在a=1之前;若输出为2,则说明a=1在foo()之前。
    function foo(){console.log(a+1)};
    

    下面來進行實驗:

    var a=1;
    console.log(foo);//若输出为function foo(){}则证明函数声明位于变量声明之前;若为undefined,说明相反。
    foo();
    function foo(){console.log(a+1)};
    
    VM1099:2 function foo(){console.log(a+1)}
    VM1099:4 2
    

    根據實驗結果,我們最後得出的排序結果是:

    function foo(){};
    var a;
    a=1;
    foo();
    

    回覆
    0
  • 黄舟

    黄舟2017-05-18 10:57:55

    雷雷

    回覆
    0
  • 取消回覆