2010-08-04 59 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

相关问题