dchhetri
dchhetri

Reputation: 7136

javascript binding object's prototype function

How would I bind the this pointer in the objects prototype to the object's instance?

function Foo(){ }
Foo.prototype.f1 = function(){this.f2();} //is wrong because 'this' does not refer to Foo instance
Foo.prototype.f2 = function(){}

This is really annoying. Can anyone help? I tried doing _.bindAll(this,'f1','f2') inside Foo's constructor but no luck.

Upvotes: 1

Views: 1751

Answers (5)

Domenic
Domenic

Reputation: 112857

This works:

function Foo() {
    this.f1 = this.f1.bind(this);
    this.f2 = this.f2.bind(this);
}

Foo.prototype.f1 = function () { this.f2(); };
Foo.prototype.f2 = function () { console.log("f2"); };

var foo = new Foo();
var f = foo.f1;
f();

http://jsfiddle.net/VYdNx/3/

As does this:

function Foo() {
    _.bindAll(this);
}

Foo.prototype.f1 = function () { this.f2(); };
Foo.prototype.f2 = function () { console.log("f2"); };

var foo = new Foo();
var f = foo.f1;
f();

http://jsfiddle.net/VYdNx/2/

Upvotes: 1

Felix Kling
Felix Kling

Reputation: 816790

You mention in a comment that you are setting f1 as event handler with:

canvas.addListner('mousedown',this.f1, false)

Instead, you can pass a closure:

var self = this;
canvas.addListner('mousedown',function() {
    self.f1();
}, false);

or use the bind methods of the Underscore.js library:

canvas.addListner('mousedown', _.bind(this.f1, this), false);

Upvotes: 1

Ryan
Ryan

Reputation: 1557

Try this:

    var Foo = function() {};
    Foo.prototype.f1 = function() {this.f2();};
    Foo.prototype.f2 = function() {};
    var foo = new Foo();
    var proxyFn = function(fooInstance) {
        fooInstance.f1();
    };
    canvas.addListener('mousedown', proxyFn(foo), false);

Or something more generic:

    var bindFunction = function(fnToBind, scopeObj) {
        return function() {  // closure scope will contain bindFunction args
            fnToBind.call(scopeObj);
        };
    };
    var Foo = function() {};
    Foo.prototype.f1 = function() {this.f2();};
    Foo.prototype.f2 = function() {};
    var foo = new Foo();
    var proxyFn = bindFunction(Foo.prototype.f1, foo);
    canvas.addListener('mousedown', proxyFn, false);

Upvotes: 1

Tran Dinh Thoai
Tran Dinh Thoai

Reputation: 702

Your code should be changed to:

function Foo() {
  this.f1 = function() {
    this.f2();
  }
  this.f2 = function() {
  }
}

Upvotes: 1

Ryan
Ryan

Reputation: 1557

Your code would work correctly if you used var foo = new Foo();. Then, just use foo.f1();. foo will be this in f1.

The reason is that when you use new against a constructor function, a _proto link will be attached to the object that will be the new instance. This _proto_ link points to the prototype of the constructor function. At runtime, if an accessed property/method of the instance does not exist on the instance directly, the interpreter will follow the _proto_, and try to access the property/method there.

If you want to call a function with an explicit object as this, you can do myFunc.call(myObjThatWillBeThis).

Upvotes: 1

Related Questions