Pherrymason
Pherrymason

Reputation: 8067

Javascript: How to access object member from event callback function

I have some problems trying to figure out what is wrong with my object design.

var comment = function(){
var textarea = null;
$(document).ready( init );

function init()
{
    $('.reply').click( comment.reply_to );
    this.textarea = $('.commentbox textarea');
    console.log( this.textarea );   // properly shows the textarea element
    console.log( textarea );        // outputs null
}

function set_text( the_text )
{
    console.log( textarea );        // outputs null
    console.log( this.textarea );   // outputs undefined
    textarea.val( the_text );
}

return {
    reply_to: function()
    {
        console.log( this );            // outputs the element who fired the event
        set_text( 'a test text' );      // properly gets called.
    }
};
}();

When document is fully loaded, init() is automatically called and initializes the object. I must note that the textarea member properly points to the desired element. A click event is attached to a "reply" button, so reply_to() function is called whenever user clicks on it.

So, this is what I don't understand: * When using "this" is safe? Using it from reply_to() it is not, as it seems like the context is set to the caller element. * Why I can call "set_text()" from reply_to, but I cannot access the "textarea" member? * How I should do to access "textarea" member from reply_to() (which is an event callback)?

Upvotes: 1

Views: 2918

Answers (1)

Nick Craver
Nick Craver

Reputation: 630389

Since inside those handlers the context will change, it's easiest to keep a reference to the context you want, I personally prefer self. Here's one alternative format:

var comment = function(){
    this.textarea = null;
    var self = this;
    $(document).ready( init );

    function init()
    {
        $('.reply').click( reply_to );
        self.textarea = $('.commentbox textarea');
    }

    function set_text( the_text )
    {
        self.textarea.val( the_text );
    }

    function reply_to() {
      set_text( 'a test text' );
    }
}();

You can test it here. Admittedly though I'm not really sure what you're trying to accomplish though. You are trying to return the reply_to function, but bind it yourself inside the init() ready handler...so you can either bind it immediately (like above), or change it up and return what you want to bind elsewhere.

Upvotes: 4

Related Questions