關閉定義和示例
回答
這裏是我如何看待一個閉包......
一個函數對象由兩件事組成。第一件事是該函數的代碼,第二件事是它執行的範圍。在閉包中,函數執行的範圍和代碼相互分離。相同的代碼可以在各種範圍內執行。
如果以完全不受限制的方式允許這會導致很大的混淆。即使它和動態範圍一樣鬆散(函數繼承了它被調用的地方的範圍),它變得非常混亂。
閉包是一種指定範圍規則的便捷方式,因爲它們只需要讀取代碼而不是跟蹤代碼,因此很有意義。在閉包中,函數獲取聲明的範圍。如果它在執行另一個函數時被聲明,它將獲得函數堆棧的特定實例的範圍。與能夠給出閉包和任意範圍或動態範圍相比,這更簡單易懂。
這裏是在Python瑣碎閉合的一個示例:
def outer():
def closure():
pass
return closure
在這裏,函數closure
是一個閉合。它實際上並沒有使用它定義的範圍中的任何變量,所以它非常微不足道,但它仍然是一個。
這裏是Python中不那麼平凡,但還是單純縫合:
def outer(x):
def closure():
return x
return closure
f1 = outer(5)
f2 = outer(6)
調用f1()
將返回5,並呼籲f2()
將返回6.正如你所看到的,功能closure
是部分代碼和部分範圍。
當outer(5)
被調用時,它爲呼叫創建一個包含一個版本的變量x
持有價值5.然後,它宣佈它獲取該範圍的功能closure
一個堆棧條目。
當outer(6)
被調用時,它爲呼叫創建一個包含一個版本的變量x
持有價值6.然後宣佈其獲取範圍功能closure
一個堆棧條目。
感謝您的解釋 – peterwkc 2010-07-21 06:37:11
閉包基本上是嵌套在可以訪問本地變量函數的內部函數B:
function A() {
var x = 5;
function B() {
print(x);
}
return B;
}
如果你來自一個C++的背景下,這是相當難以消化。當我們嘗試調用A返回的函數時,它會引用什麼x
?那x
不會因爲A()
終止而無效嗎?
答案是x
實際上仍然存在。我們回到的B
實際上帶着它隱含地帶着x
。很酷,呃?
從一般意義上講,閉包是一個綁定到某些數據的函數。在沒有像C這樣的閉包的語言中,每個程序都有固定數量的函數。使用閉包,從某種意義上說,您可以通過將它們綁定到動態數據來「創建函數」。當然,沒有人阻止你模仿C語言中的閉包,但有時候這可能是一種痛苦。
關閉是非常有用的。例如,假設我們要實現我們自己的「for循環」:
function loop(count, f) {
for (var i = 0; i < count; i++)
f(i);
}
var array = [0,1,2,3,4];
loop(5, function(i) {
print(array[i]);
});
被允許訪問外部的變量沒有做一堆額外的廢話保持代碼簡單好用。如果沒有關閉,您可能需要一個上下文變量傳遞給loop
函數:
function loop(count, f, ctx) {
for (var i = 0; i < count; i++)
f(i, ctx);
}
var array = [0,1,2,3,4];
loop(5, function(i, ctx) {
print(ctx[i]);
}, array);
又如:假設我們想註冊在jQuery的回調,但它可能長的功能和它的調用者後執行,它的調用者的調用者完成運行:
$(document).ready(function(){
var clicked = 0;
$('#button').click(function(){
clicked++;
alert("You've pressed the button " + clicked + " times.");
});
});
如果JavaScript的是更喜歡C++(之前的C++ 0x),這clicked
變量將由時間長了給$(document).ready()
函數被調用,按鈕點擊回調會有未定義的行爲。
有趣的是,C++ 0x現在有一個lambdas,它可以從它們的封閉範圍中捕獲變量。所以*「如果你來自C++背景」*參數變得不那麼重要。 – 2010-07-21 04:29:58
這很酷。謝謝。 – LandonSchropp 2010-07-21 04:35:30
@Alexandre Jasmin - 這些都是非常奇怪的封閉形式。比支持它們的大多數語言更加明確。雖然我其實更喜歡那種方式。我認爲你__應該必須說明你打算從封閉範圍使用哪些變量。 – Omnifarious 2010-07-21 04:56:28
如果您想關閉一個例子,我建議你檢查書
深入Python:第六章 - 瓶蓋&發電機
書其開放&免費的,你可以在下載--->http://diveintopython3.org/
這個例子很有趣,很清楚,並逐漸採取了更先進的方法。 對於第一次曝光其偉大的我認爲。
看看它,沒有理由在這裏重現它,只要你可以簡單地下載它或在線閱讀它。
- 1. C++ 0x關閉/ lambdas示例
- 2. Python /關閉未定義
- 3. Javascript關閉:MDN中的實際關閉示例
- 4. Javascript關閉的實際用法/示例
- 5. 麻煩理解Javascript關閉示例
- 6. 快速關閉省略示例?
- 7. AndEngine強制關閉加載示例
- 8. Android Renderscript示例強制關閉
- 9. 理解關閉示例難點
- 10. 關閉和顯示MFMessageComposeViewController
- 11. C#中的事件 - 定義和示例
- 12. MVVM關閉標籤示例的任何代碼示例?
- 13. 在Windows Azure中關閉特定實例
- 14. 從Swagger定義生成示例請求和響應定義
- 15. 打開和關閉綁定
- 16. 綁定和關閉groovy
- 17. JSP自定義關閉窗體標籤顯示錯誤點
- 18. 如何顯示自定義關閉對話框?
- 19. 自定義ErrorTemplate關閉屏幕顯示錯誤
- 20. GWT - 在窗口關閉之前顯示自定義對話框?
- 21. 如何在數據庫關閉時顯示自定義消息
- 22. 當Weblogic服務器關閉時顯示自定義消息
- 23. 弱自我封閉和後果示例
- 24. 自定義彈出窗口關閉
- 25. 如何關閉自定義對話框
- 26. 關閉clicklistener上的自定義alertdialog
- 27. 的Javascript關閉定義別處
- 28. 自動關閉Chrome自定義標籤
- 29. 正確關閉自定義對話框
- 30. jquery疊加 - 如何自定義關閉
問題http://stackoverflow.com/questions/36636/what-is-a-closure和http://stackoverflow.com/questions/1095707/what-is-the-exact-definition-of-a-閉包與此類似 – 2010-07-21 04:12:29