1

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.

Rob W
351k87 gold badges811 silver badges683 bronze badges
asked Oct 17, 2011 at 5:59
0

5 Answers 5

1

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);
answered Oct 17, 2011 at 6:47
Sign up to request clarification or add additional context in comments.

Comments

1

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).

answered Oct 17, 2011 at 6:11

1 Comment

The problem is, sorry I wasn't clear, imagine f1 being a onMouseDown function calling f2, where the onMouseDown is a registered as a listener for canvas via canvas.addListner('mousedown',this.f1,false) in Foo's constructor
1

Your code should be changed to:

function Foo() {
 this.f1 = function() {
 this.f2();
 }
 this.f2 = function() {
 }
}
answered Oct 17, 2011 at 6:13

1 Comment

That is what I ended up doing, but that is just ugly. I would prefer to 'separate' out the interface
1

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);
answered Oct 17, 2011 at 6:22

Comments

1

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/

answered Oct 17, 2011 at 6:34

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.