jckdnk111
jckdnk111

Reputation: 2368

JS prototypical function 'this' confusion

I'm using a JSON-RPC lib in nodejs. I register my functions by name (e.g. rpc({publicName: privateFunction})) and the RPC lib invokes the functions for me and handles marshalling the JSON and function arguments. It works great for simple functions but it breaks when I pass it a prototypical function (a function defined on the prototype chain of an object). The problem is the RPC lib is invoking the function using apply which alters the context of this so I can no longer access the other prototype properties / functions.

Here is an example of the problem:

var MyObj = function(prop1,prop2,prop3){
    this.prop1 = prop1;
    this.prop2 = prop2;
    this.prop3 = prop3;
}

MyObj.prototype.showProps = function(separator){
    console.log(this.prop1 + separator + this.prop2 + separator + this.prop3);
}

var myObjInstance = new MyObj('a', 'b', 'c');
myObjInstance.showProps(',');

// displays a,b,c


// I register the function as rpc({show_props:myObjInstance.showProps}) and the RPC lib calls it like
myObjInstance.showProps.apply(this, [',']);

// displays undefined,undefined,undefined

Is there a better technique to fix this? Is there a way to preserve the context of this inside the prototypical function?

Upvotes: 0

Views: 162

Answers (2)

David Hellsing
David Hellsing

Reputation: 108500

You can use Function.bind() to bind a specific context to a function. It’s not avail in all environments, but there is a shim on the MDN page that you can use if you need legacy support.

So in your example you could add:

myObjInstance.showProps = myObjInstance.showProps.bind(myObjInstance);

Upvotes: 3

Halcyon
Halcyon

Reputation: 57729

In the last line:

myObjInstance.showProps.apply(this, [',']);

this points to the global scope (or whatever scope you're in at that point, it does not point to myObjInstance). You should call it like this:

myObjInstance.showProps.apply(myObjInstance, [',']);

The first argument is the context, which should be your object instance.

Upvotes: 0

Related Questions