1

I'm instantiating an Object which creates a DOM element and stores a jQuery Object as one of it's properties, e.g.:

this.element = $("<div></div>");

I noticed that when establishing events, jQuery's rewriting of thethis context can cause issues, such as if you tried to apply the following:

this.element.click(function() {
  this.someObjectMethod();
});

The inner this now applies to the DOM element and not the original Object. To overcome this, I can do the following:

var _this = this;
this.element.click(function() {
  _this.someObjectMethod();
});

I'm wondering, is bad practice and is there a better way? I've looked at some jQuery docs on apply and call but I'm not sure they'd help in this situation.

Additionally, I'm using Resig's 'simple inheritence 'Class, which might make a difference to your answers.

Update on seeing the $.proxy answers, these seem reasonable solutions, however you then lose the ability to reference the DOM element.

Ian Clark
  • 9,237
  • 4
  • 32
  • 49
  • 1
    the practice of assigning `this` to another variable is the standard. people generally use `self` or `that` as the name (I prefer `that` as `self` shadows `window.self`) – jbabey Aug 13 '13 at 13:15
  • possible duplicate of [Controlling the value of 'this' in a jQuery event](http://stackoverflow.com/questions/520019/controlling-the-value-of-this-in-a-jquery-event) – CodingIntrigue Aug 13 '13 at 13:15
  • @jbabey - I've also seen `self` used, though I must admit I find it slightly confusing to use the words interchangably, so I just felt prefixing the `this` might be clearer to me. I like your suggestion of `that` though, might adopt it! Thanks – Ian Clark Aug 13 '13 at 13:18

1 Answers1

2

You can use $.proxy():

this.element.click($.proxy(function() {
    this.someObjectMethod();
}, this));

It returns a function that will always be invoked in the context of the object you specify in the second argument (in our case, the outer this).

$.proxy() also enforces a special case with event handlers: if you pass the original, unproxied method to off() or unbind() later, the proxied handler will be transparently removed even though you did not specify it directly.

Frédéric Hamidi
  • 258,201
  • 41
  • 486
  • 479
  • Thanks Frederic, though the outcome is very similar, and then I lose the reference to the jQuery element. I wonder if it would even be quicker to just assign a reference to `_this` than to apply the jQuery proxy method. – Ian Clark Aug 13 '13 at 13:17
  • @Ian, I don't understand why you lose the reference to the jQuery object. Surely, it is available as `this.element`, since `this` is still your plugin object. – Frédéric Hamidi Aug 13 '13 at 13:18
  • Good point well made @Frederic, but lets say you had a more complex $(".inside", this.element) – Ian Clark Aug 13 '13 at 13:19
  • @Ian, then you'd be better off with an additional `_this` or `that` or `self` variable indeed :) – Frédéric Hamidi Aug 13 '13 at 13:21
  • This was useful, but I don't like the fact that you lose the reference to the DOM element. I just kept my original code in the end, but I did learn that the `$.proxy` method exists and has some applications :) – Ian Clark Aug 22 '13 at 14:43