Question

Consider the following Javascript class:

function ClassA() {
 this.someVariable = someValue;
 this.myHandler = function(){
   // I WANT TO CALL InnerFunction
   this.innerFunction();
 };

 this.innerFunction = function(){
   // do something that accesses/manipulates someVariable
 };

 this.hookUp = function(id){
   document.getElementById(id).onclick = this.myHandler;
 };
};
...
...
var button = document.createElement('button');
button.setAttribute('id','mybuttonid');
// append button to the document
...
...
var x = new ClassA();
x.hookUp('mybuttonid');

When I click on the button, the handler executes, however, 'this' now refers to the button element instead of the ClassA object, so it cannot resolve innerFunction().

What i need to have is a way to indicate to the handler that the context of this is the instance of ClassA (similar to $.ajax({context: this....}) where you can use 'this' in the .done() or .error() handlers), or a way to pass a reference to the instance to the handler without making the handler execute at instantiation time. For example if I try to pass 'this' as a praremter to myHandler (myHandler=function(ref){}, and then change : document.getElementById(id).onclick = this.myHandler(this);) But as you add parameters to myHandler, the function is executed at class instantiation time instead of at click time.

Any help will be greatly appreciated.

Was it helpful?

Solution

Replace...

this.myHandler = function(){
    this.innerFunction();
};

... with ...

var self = this;
this.myHandler = function() {   
    self.innerFunction();
};

See this article by Crockford. Cite:

By convention, we make a private that variable. This is used to make the object available to the private methods. This is a workaround for an error in the ECMAScript Language Specification which causes this to be set incorrectly for inner functions.

See also What does 'var that = this;' mean in JavaScript?

OTHER TIPS

Like you already discovered, the value of this depends on how the method is called. Thus, it can be confusing when using this within event handlers attached to DOM elements.

Instead, when adding handlers, use an an anonymous method along with a variable within a closure.

For example, change your hookup function to be:

this.hookUp = function(id) {
    var _this = this;
    document.getElementById(id).onclick = function() {
      _this.innerFunction();
    }
}

Notice that you no longer depend on this from within the onclick handler and thus avoid the problem. Once you're in innerFunction, you can continue to use this as you normally would, as it now correctly points to the correct object.

For a deeper explanation on how this works in functions, MDN has a nice article about the this keyword.

this is a commonly solved using what's called 'Proxy Pattern'.

I think this will help (-!

http://addyosmani.com/resources/essentialjsdesignpatterns/book/#proxypatternjquery

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top