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.

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

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() {
  }
}

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

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/

Comments

Your Answer

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.