Reputation: 5263
I can't figure this one out:
I have a function, e.g.
function test () { this.rating = 0; $j('#star_rating a').click(function() { alert(this.rating); }); } var foo = new test();
On click it alerts "undefined". What is wrong? Please help.
Upvotes: 2
Views: 194
Reputation: 92274
Like others have said, "this" is different in test and the anonymous function passed to click().
test is a global function, therefore, "this" is a reference to the window (global) object. What you are actually doing is setting a global variable, probably not an intended side-effect. (use alert(window.rating) to see what I mean)
For your example, there is no need to use "this", though I think your example is just to demonstrate a point. If it were real code, tt should be converted to:
function test () {
var rating = 0;
$j('#star_rating a').click(function() {
alert(rating); //Use the closure defined in the outer function
});
}
The point is that you shouldn't use "this" from global functions.
Upvotes: 1
Reputation: 30555
If you want to keep a this
-like reference around inside an object for use later where this
will probably mean something else, it's a common trick to assign this
to a local instance variable. I use self
.
function test () {
var self = this;
self.rating = 0;
$j('#star_rating a').click(function() {
alert(self.rating);
});
}
var foo = new test();
The advantage of this trick is that inside all code in your object - even closures - self
will always refer to the object. You can also use this
to refer to whatever it normally means.
Upvotes: 1
Reputation: 57685
Inside the .click()
the this
refers to the item clicked. So the context is different than when you set rating
. Those two this
s are different.
You need to conserve the context somehow.
Also, you may want to return false;
or event.preventDefault()
if you are clicking on a link and you don't want the page to refresh
function test () {
this.rating = 0;
var oldThis = this; // Conserving the context for use inside .click()
$j('#star_rating a').click(function() {
alert(oldThis.rating);
return false; // Use this if you don't want the page to change / refresh
});
}
var foo = new test();
Upvotes: 5
Reputation: 37761
The this
is different in both cases. Try using breakpoints in firebug to see what they are set to.
Upvotes: 0
Reputation: 546045
Inside the function, "this" is the element which has been clicked on, which is different to "this" outside the function. A simple fix:
function test () {
this.rating = 0;
var self = this;
$j('#star_rating a').click(function() {
alert(self.rating);
});
}
Upvotes: 2