javascriptfunction-prototypesprototype-programming

Passing a prototype's function as parameter without losing the 'this' context


I'm defining a 'class' in JavaScript by means of prototype.

The first time func() runs, it works, but when it's called the second time, through a setTimeout, it fails because this time it has lost the object context, I.E. this doesn't reference the object anymore but now references window.

Is there a way I can overcome this while still using prototype? or do I need instead to use closures to define a 'class'?

function klass(){}

klass.prototype = {
  a: function() {
    console.log( "Hi" );
  },    
  func: function(){
    this.a();
    setTimeout( this.func, 100 );
  }
};

var x = new klass();
x.func();

Solution

  • Use Function.prototype.bind:

    setTimeout( this.func.bind(this), 100 );
    

    From Mozilla Developer Network:

    https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/Function/bind

    if (!Function.prototype.bind) {  
      Function.prototype.bind = function (oThis) {  
        if (typeof this !== "function") {  
          // closest thing possible to the ECMAScript 5 internal IsCallable function  
          throw new TypeError("Function.prototype.bind - what is trying to be bound is not callable");  
        }  
      
        var aArgs = Array.prototype.slice.call(arguments, 1),   
            fToBind = this,   
            fNOP = function () {},  
            fBound = function () {  
              return fToBind.apply(this instanceof fNOP  
                                     ? this  
                                     : oThis || window,  
                                   aArgs.concat(Array.prototype.slice.call(arguments)));  
            };  
      
        fNOP.prototype = this.prototype;  
        fBound.prototype = new fNOP();  
      
        return fBound;  
      };  
    }