Reputation: 7136
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
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();
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();
Upvotes: 1
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
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
Reputation: 702
Your code should be changed to:
function Foo() {
this.f1 = function() {
this.f2();
}
this.f2 = function() {
}
}
Upvotes: 1
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