views:

41

answers:

5

Hi, 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.

+5  A: 

Inside the .click() the this refers to the item clicked. So the context is different than when you set rating. Those two thiss 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();

Try it out with this jsFiddle

Peter Ajtai
+2  A: 

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);
  });
}
nickf
A: 

The this is different in both cases. Try using breakpoints in firebug to see what they are set to.

Douglas
+1  A: 

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.

staticsan
+1  A: 

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.

Juan Mendes