Ankur
Ankur

Reputation: 2901

Closing around a variable in an event handler

I know there is a smart way to utilize closures and do what I am looking for, but I'm not sure what it is.

In the following code:

var MyApp = {
  innerObject : {
    myData : "test value",
    myMethod : function() {
      // 'this' ends up referring to HTMLElement, not what I want 
      alert(this.myData);
    }
  }
  open : function() {
    document.getElementById('connectLink').addEventListener('click', this.innerObject.myMethod, false);
  }
}
MyApp.open();

I am looking to attach an event handler to the element with id = 'connectLink' to a method inside innerObject. That method accesses other data inside innerObject to carry out its function. I know this has something to do with the tricky nature of the keyword this in javascript. Is there a pattern I can adopt to fix this?

Upvotes: 1

Views: 97

Answers (2)

Felix Kling
Felix Kling

Reputation: 816790

Keep a reference to this and pass an anonymous function:

var self = this;
document.getElementById('connectLink').addEventListener('click', function() {
    self.innerObject.myMethod();
}, false);

Also remember that you have to use attachEvent in IE.

Update:

Newer browsers provide .bind() which lets you bind the context of the function to a certain object. This is probably the cleanest solution. The link above provides an implementation for browsers that don't support it.

el.addEventListener(
    'click', 
    this.innerObject.myMethod.bind(this.innerObject), 
    false
);

Upvotes: 1

RobG
RobG

Reputation: 147453

Note that by convention, identifiers starting with a capital letter represent constructors.

Remeber that this is set by the call, not by the declaration or initialisation (except for ES 5 bind, which isn't ready for use on the general web yet).

You can do:

myMethod : function() {
      alert(MyApp.innerObject.myData);
}

Or you can create MyApp using the module pattern to keep a reference to innerObject (there are some who think it's overused). But even so, this within the listener will reference the element it is set on.

Upvotes: 2

Related Questions