簡體   English   中英

返回后定義函數

[英]Defining functions after return

我正在閱讀John Papa的AngularJS風格指南,並看到了代碼

function dataService() {
    var someValue = '';
    var service = {
        save: save,
        someValue: someValue,
        validate: validate
    };
    return service;

    ////////////

    function save() {
        /* */
    };

    function validate() {
        /* */
    };
}

您可以看到函數savevalidate函數返回值定義的。 這是如何運作的? 它是否符合標准並適用於所有瀏覽器(例如,來自IE 6)?

您可以看到函數savevalidate是在函數返回值后定義的。

這就是從它們寫入的地方看起來的樣子,是的,但實際上它們是在函數中的任何分步代碼運行之前定義的。 有時這被稱為“提升”聲明到函數的頂部(類似的情況也發生在var ;更多下面)。

當控件進入執行上下文時(例如,當您輸入函數時,在程序開頭輸入全局環境,或輸入eval代碼), 在執行任何分步代碼之前發生的幾件事之一是處理該上下文中的所有函數聲明並創建這些函數。 由於savevalidate是由函數聲明定義的,因此它們是在代碼的第一個逐步行之前創建的,因此它們在return之后並不重要。

以下是JavaScript引擎在調用函數時所執行的操作(例如,在調用dataService ),並突出顯示了函數聲明步驟:

  1. 設置的值, this
  2. 為呼叫創建一個新環境(讓我們稱之為env
  3. env上設置對函數[[Scope]]屬性的引用(這是閉包工作方式的一部分)
  4. 為環境創建一個綁定對象 (讓我們稱之為bindings )來保存我們由函數定義的各種名稱(這是閉包如何工作的另一部分,以及如何解析變量引用)
  5. 如果函數具有名稱,請將其作為引用該函數的屬性添加到bindings
  6. 將正式函數參數添加到bindings
  7. 處理函數聲明,將其名稱添加到bindings
  8. 創建arguments對象,將其添加到bindings
  9. 將使用var聲明的每個變量添加到bindings (如果尚未定義),並使用值undefined
  10. 處理函數中的逐步代碼
  11. 設置調用表達式的結果

這在§10.4.1中的規范及其鏈接的部分中以極其詳細的方式列出 (如果你去閱讀那個,自我鼓勵,散文就是......不穩定......)這是當前規范的一個鏈接,但這在1999年舊版第三版規范的§10中也有明確規定,而且我很確定從一開始就是如此。

它是否符合標准並適用於所有瀏覽器(例如,來自IE 6)?

是。 它曾經讓我感到緊張,所以幾年前(可能〜2005年)我在我能找到的所有當時和非常死的瀏覽器(包括IE6)上證明了這一點,並且它得到了普遍正確的處理。 這實際上並不令人驚訝,因為它是使這段代碼工作的原因:

doSomething();

function doSomething() {
    // ....
}

......人們這樣做, 所有的時間


這種“提升”是函數聲明和函數表達式之間的關鍵差異之一。 如果savevalidate是由函數表達式創建的,那么return后寫入它們會很重要 - 它們永遠不會被創建:

// It wouldn't work like this, for instance
function dataService() {
    var someValue = '';
    var service = {
        save: save,             // `save` has the value `undefined` at this point
        someValue: someValue,
        validate: validate      // So does `validate`
    };
    return service;

    ////////////

    var save = function() {      // Now this is a function expression
        /* */
    };

    var validate = function() {  // This too
        /* */
    };
}

將創建savevalidate變量(由於上面的步驟9),但是在使用它們的地方,它們的值undefined ,因此返回的對象將沒有用處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM