2010-08-04 32 views
5

我有一些工作的JavaScript操縱一些DOM元素。問題是,我不明白爲什麼它的作品,這是從來沒有好事。我想了解更多關於面向對象的JavaScript和JavaScript最佳實踐,所以組織可能看起來有點奇怪。

基本上,我包裝了兩個方法來操作CSContent對象內的DOM。我在$(document).ready中創建該對象的一個​​實例content,並將一些事件綁定到content中的函數。然而,我很困惑這些功能在$(document).ready退出後仍然可以調用。這是不是說content已經超出範圍,並且它的功能不可用?總之,這裏是代碼:

+0

你能舉一個例子說明你可以在哪裏訪問'內容'嗎? – 2010-08-04 19:44:49

+0

@Pekka:當在id爲'edit-cscontent-cs-content-tweet'的元素中按下或按下某個鍵時,例如? – 2010-08-04 19:47:29

+0

@Marcel ahh,這就是他的意思!這是一個關閉。但是你已經在解釋你的答案了 - 會+1,但我今天沒有投票權。 – 2010-08-04 19:48:46

回答

2

我假設你想知道爲什麼事件處理程序像

$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea); 

工作?

那麼你不通過content作爲事件處理函數,但包含在content.toggleTweetTextarea中的函數。並且此參考在content不存在後仍然存在。沒有什麼特別的。您只是將一個對象(函數)分配給另一個變量。只要至少存在一個對象的引用,對象就不會被垃圾收集。

現在你可能會問,爲什麼這些功能仍然可以訪問tweetTextArea?這確實是一個封閉。當功能通過new CSContent()創建時,此功能的激活上下文被添加到內部函數CSContent.toggleTweetTextareaCSContent.updateTweetCharacterCount的範圍鏈中。因此,即使您沒有對content的引用,該函數的作用域仍包含在其他函數的作用域鏈中。

ready()完成後,您將無法再訪問content中包含的對象,這確實超出了範圍。

5

這m'lord,稱爲閉包:局部變量content將保留在內存中後$(document).ready退出。這也是內存泄漏的一個已知原因。

簡而言之,您將此函數綁定到DOM元素的事件偵聽器,然後JavaScript垃圾回收器知道它應該保持本地變量不變。除非事件被觸發,否則不能直接調用它(在函數之外)。對於某些人,如果您確實想在之後調用該功能(例如,使用element.click()來模擬點擊),則可以「手動」進行此操作。

+0

但除此之外,它們很棒! :)一些額外的閱讀:https://developer.mozilla。org/en/JavaScript/Guide/Closures – 2010-08-04 19:49:16

+0

因此,它可以訪問CSContent構造函數中聲明的局部變量,因爲它是一個閉包,並且它不會超出範圍,因爲它綁定到事件偵聽器?還是整個封閉被複制到事件監聽器? – jergason 2010-08-04 19:57:08

+0

@Jergason:第一個。 – 2010-08-04 19:58:55

1

今天我的大腦關閉了,但是不應該在這種情況下使用關閉嗎?

$('#edit-cscontent-cs-content-twitter').change( 
    function(){ 
     content.toggleTweetTextarea(); 
    } 
); 
+0

今天....? :)嘿埃裏克你有沒有看到這個評論:http://stackoverflow.com/questions/3274044/best-book-on-ajax/3306936#3306936 – 2010-08-04 19:54:06

+0

嗯,好主意,關閉。但是OP已經在使用一個...:P – 2010-08-04 19:57:10

相關問題