views:

102

answers:

4

Sample code:

function TestClass() {

this.init = function() {

 this.updateHeader(); // <-- error line

};

this.updateHeader = function() {
 console.log("Works");
};

};
var test = new TestClass();
$(document).ready(test.init);

When I run that in Firefox 3.5, Firebug gives me an error, saying that this.updateHeader is not a valid function. I'm a Java/PHP programmer and having some trouble understanding the Javascript OO-model. What am I doing wrong?

It does work if I replace the $(document).ready-line with simply test.init(), but I don't want that.

+1  A: 

The "this" in that context is scoped to the function it is contained within.

Janie
+1  A: 

Try $(document).ready(function () { test.init(); });

ready() expects a function as an argument, which it will execute when the document is ready. When it does, this will point to the document object, not test.

The solution is to pass it a function that explicitly calls init with the code, test.init(). When you call it that way, this (in the init function) points to your test object.

Patrick McElhaney
+3  A: 

Supplying test.init to the document ready function is really feeding it a function pointer to the init function in test.

Essentially it is ripping out the init function and executing it in the scope of the document ready function.

If you ran it as $(document).ready(function () { test.init(); } ); (As Patrick stated) it will execute in the proper scope.

Tom Hubbard
+4  A: 

By passing the function test.init directly to the ready() function, you are registering test.init as a callback function. jQuery (which, judging from your syntax, you're using) will use the callback function that it is given and apply it in the context of document. This means that the this keyword will refer to the document.

What you should do to avoid this, as suggested, is use an anonymous function (closure) that will call the function you are referring to:

$(document).ready(function() {
    test.init();
});

Using the function() { } syntax to define closures to be set as callback functions is a common pattern in Javascript.

molf
When you think about it, it makes sense :)
Bart van Heukelom