jer*_*son 5 javascript jquery closures
我有一些工作Javascript来操纵一些DOM元素.问题是,我不明白它为什么会起作用,这从来都不是一件好事.我正在尝试更多地了解面向对象的javascript和javascript最佳实践,因此组织可能看起来有点奇怪.
基本上,我包装了两个操纵CSContent对象内部DOM的方法.我创建对象的实例,content在$(document).ready并绑定一些事件中的功能content.但是,我很困惑如何在$(document).ready退出后仍然可以调用这些函数.这是不是意味着content已超出范围,其功能不可用?无论如何,这是代码:
function CSContent() {
var tweetTextArea = document.getElementById('cscontent-tweet'),
tweetTextElement = document.getElementById('edit-cscontent-cs-content-tweet'),
charCountElement = document.getElementById('cscontent-tweet-charactercount');
this.toggleTweetTextarea = function () {
$(tweetTextArea).slideToggle();
};
this.updateTweetCharacterCount = function () {
var numOfCharsLeft = 140 - tweetTextElement.value.length;
if (numOfCharsLeft < 0) {
$(charCountElement).addClass('cscontent-negative-chars-left');
}
else {
$(charCountElement).removeClass('cscontent-negative-chars-left');
}
charCountElement.innerHTML = '' + numOfCharsLeft + ' characters left.';
};
}
$(document).ready(function () {
var content = new CSContent();
//If the twitter box starts out unchecked, then hide the text area
if ($('#edit-cscontent-cs-content-twitter:checked').val() === undefined) {
$('#cscontent-tweet').hide();
}
$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea);
//Seems wasteful, but we bind to keyup and keypress to fix some weird miscounting behavior when deleting characters.
$('#edit-cscontent-cs-content-tweet').keypress(content.updateTweetCharacterCount);
$('#edit-cscontent-cs-content-tweet').keyup(content.updateTweetCharacterCount);
content.updateTweetCharacterCount();
});
Run Code Online (Sandbox Code Playgroud)
这个,m'lord,被称为闭包:本地变量content将在$(document).ready退出后保留在内存中.这也是内存泄漏的已知原因.
简而言之,您将此函数绑定到DOM元素的事件侦听器,然后JavaScript垃圾收集器知道它应该保持本地变量不变.除非事件被触发,否则不能直接调用它(在函数外部).如果您真的想在之后调用该函数(例如,使用element.click()模拟点击),您可以"手动"执行此操作.
我假设您想知道为什么事件处理程序喜欢
$('#edit-cscontent-cs-content-twitter').change(content.toggleTweetTextarea);
Run Code Online (Sandbox Code Playgroud)
工作?
好吧,您不传递content事件处理程序,而是传递content.toggleTweetTextarea. content并且这个引用在不存在之后仍然存在。没有什么特别的。您刚刚将一个对象(函数)分配给另一个变量。只要至少存在一个对对象的引用,该对象就不会被垃圾收集。
现在你可能会问为什么这些函数仍然可以访问eg tweetTextArea?这确实是一个封闭。当通过 创建函数时,该函数的激活上下文将添加到内部函数和new CSContent()的作用域链中。因此,即使您不再引用该函数,该函数的作用域仍然包含在其他函数的作用域链中。CSContent.toggleTweetTextareaCSContent.updateTweetCharacterCountcontent
content完成后您将无法再访问其中包含的对象ready(),这确实超出了范围。
| 归档时间: |
|
| 查看次数: |
527 次 |
| 最近记录: |