2012-11-21 96 views
5

就像我讀過的文章一樣多,我仍然有一些問題。Javascript關閉說明?

我已經知道(和理解)關閉的像用法:

  1. 臭名昭著的循環問題(與保持數量與戒備在他們中的每一個環節環)

  2. 增加計數器(繼續呼叫功能 - >哪些提醒增加數字)

here

內部函數指的是其外部函數 的局部變量創建封閉

here

的封閉爲函數的局部變量 - 在 函數返回之後保持活動狀態,或者閉包是一個不是 的分配棧d函數返回時。 (就好象一個 '堆棧幀' 是 malloc分配的而不是在堆棧上!)

3個問題請:

問題#1

有人告訴我,所有的JS中的函數創建閉包。

什麼 ???如果我用私有變量創建一個正常的函數,它只是創建一個範圍。不關閉。

我覺得這樣封閉工作:(from here

  1. 製作外, 「功能機」 的功能。
  2. 在其中聲明一個局部變量。
  3. 在外部聲明一個內部函數。
  4. 在內部函數中使用外部函數的變量。
  5. 有外部函數返回的內部函數
  6. 運行的功能,它的返回值賦值給一個變量

exmample:

function functionMaker(){ 
    var x = 1; 
    function innerFunction(){ 
    alert(x); 
    x++; 
    } 
    return innerFunction; 
} 

那麼,爲什麼他們說每個js函數創建閉包?

問題2

是否Self-Invoking Functions又名IEFA - Immediately Invoked Function Expression創建一個封閉?

看着

(function (a) { 
    alert(a); 
})(4); 

我沒有看到像上面的6規則模式: 正是Have the outer function return the inner function是在這裏嗎?我看不到字return

問題#3

function myFunction() { 
  var myVar = 1; 
  var alertMyVar = function() { 
    alert('My variable has the value ' + myVar); 
  }; 
  setTimeout(alertMyVar, 1000 * 3600 * 24); 
} 
myFunction(); 

是否myFunction還活着,全日在這裏?或者在setTimeout之後立即結束?如果是這樣,怎麼SetTimeOut想起價值?

請幫我得到它的權利。

回答

8

所有功能調用創建一個封閉。重要的是要注意封閉是否超出了函數調用的生命週期。

如果我做了一個立即執行的功能:

var value = (function() { 
    return 4; 
})(); 

然後封閉被創建,但放棄當函數返回。爲什麼?因爲沒有對閉包中定義的符號的存活引用。但在這裏:

var value = function() { 
    var counter = 0; 
    return function() { 
    return counter++; 
    }; 
}(); 

封閉住在立即執行功能後,因爲它返回另一個功能,又包括在原函數中定義的「計數器」符號引用。由於返回的函數仍然「活着」,因此閉包必須由運行時系統保留。

注意這裏:

var value = function() { 
    return function(a) { 
    return "hello " + a; 
    }; 
}(); 

即使外立即執行函數返回一個函數,該函數不從外一個引用任何符號,所以沒有必要保持關閉。

我猜我想說的是,它有助於思考的封閉物的執行功能,而不是嚴格的靜態,結構的東西效果的一部分。有可能有一個功能,有時創建一個持久閉包,但並不總是。

+0

感謝。它與我的第3個問題有關嗎? '在函數調用的生命週期之外? –

+0

記住:JavaScript的IIFEs必須有括號:'(函數(){})();' –

+2

@WaleedKhan不,那是不正確的。只需要消除'function'關鍵字的歧義。在'='表達式的右邊沒有歧義,所以括號不是必需的。 – Pointy