为什么这个 Javascript 对象在 $(document).ready 之后没有超出范围?

发布于 2024-09-13 09:28:01 字数 1895 浏览 3 评论 0原文

我有一些有效的 Javascript 可以操作一些 DOM 元素。问题是,我不明白为什么它有效,这从来都不是一件好事。我正在尝试了解更多有关面向对象的 javascript 和 javascript 最佳实践的信息,因此该组织可能看起来有点奇怪。

基本上,我将两个操作 DOM 的方法包装在 CSContent 对象内。我在 $(document).ready 中创建该对象 content 的实例,并将一些事件绑定到 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();
});

I have some working Javascript that manipulates the some DOM elements. The problem is, I don't understand why it works, which is never a good thing. I am trying to learn more about object oriented javascript and javascript best practices, so the organization may seems a little strange.

Basically, I wrap two methods that manipulate the DOM inside a CSContent object. I create an instance of that object, content in $(document).ready and bind some events to the functions in content. However, I am confused as to how these functions can still be called after $(document).ready exits. Doesn't that mean that content has gone out of scope, and its functions are not available? Anyway, here is the code:

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();
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

む无字情书 2024-09-20 09:28:01

大人,这称为闭包:局部变量 content$(document).ready 退出后将保留在内存中。这也是内存泄漏的已知原因。

简而言之,您将此函数绑定到 DOM 元素的事件侦听器,然后 JavaScript 垃圾收集器知道它应该保持局部变量完整。您不能直接调用它(在函数之外),除非事件被触发。对于某些,如果您确实想稍后调用该函数(例如,使用 element.click() 来模拟点击),您可以“手动”执行此操作。

This, m'lord, is called a closure: the local variable content will remain in memory after $(document).ready exits. This is also a known cause of memory leaks.

In short, you bind this function to an event listener of a DOM element and then the JavaScript garbage collector knows that it should keep the local variable intact. You can't call it directly (outside of the function), unless the event is triggered. With some, you can do this ‘manually’, if you really want to call the function afterward (e.g., using element.click() to simulate a click).

奢欲 2024-09-20 09:28:01

我想您想知道为什么事件处理程序喜欢

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

工作?

那么,您不会将 content 作为事件处理程序传递,而是传递 content.toggleTweetTextarea 中包含的函数。并且在 content 不再存在后,该引用仍然存在。没有什么特别的。您刚刚将一个对象(函数)分配给另一个变量。只要至少存在一个对对象的引用,该对象就不会被垃圾收集。

现在您可能会问为什么这些函数仍然可以访问例如 tweetTextArea ?这确实是一个封闭。当通过 new CSContent() 创建函数时,该函数的激活上下文将添加到内部函数 CSContent.toggleTweetTextareaCSContent 的作用域链中。更新TweetCharacterCount。因此,即使您不再引用 content,该函数的作用域仍然包含在其他函数的作用域链中。

ready() 完成后,您将无法再访问 content 中包含的对象,这确实超出了范围。

I assume you wonder why the event handlers like

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

work?

Well you don't pass content as event handler but the function that is contained in content.toggleTweetTextarea. And this reference will still exist after content does not exist anymore. There is nothing special about it. You just assigned an object (the function) to another variable. As long as at least one reference to an object exists, the object won't be garbage collected.

Now you may ask why those functions have still access to e.g. tweetTextArea ? This is indeed a closure. When the functions are created via new CSContent(), the activation context of this function is added to the scope chain of the inner functions CSContent.toggleTweetTextarea and CSContent.updateTweetCharacterCount. So even if you don't have a reference to content anymore, the scope of this function is still contained in the scope chain of the other functions.

You won't be able to access the object contained in content anymore after ready() is finished, this indeed goes out of scope.

不必了 2024-09-20 09:28:01

我今天脑子不好使了,但是在这种情况下你不应该使用闭包吗?

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

My brain is off today, but shouldn't you be using closures in this situation?

$('#edit-cscontent-cs-content-twitter').change( 
    function(){ 
        content.toggleTweetTextarea(); 
    } 
);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文