Reputation: 48566
Suppose you have
function Thing () {
this.val = 1;
}
Thing.prototype.some = function () {
console.log('thing');
};
Thing.prototype.foo = {
bar: function () {
console.log(root.val);
}
};
How would you be able to get a reference to this
as in the Thing
instance, while still sticking to a prototypal model?
Upvotes: 1
Views: 66
Reputation: 37005
You can bind function to a context without executing it like call
/ apply
does. Use bind
.
For example:
function Thing () {
this.val = 1;
}
Thing.prototype.some = function () {
console.log('thing');
};
Thing.prototype.foo = {
bar: function () {
console.log(this.val);
}
}
var thing = new Thing();
// bind instance's `foo.bar` to `thing` instance
thing.foo.bar = thing.foo.bar.bind( thing );
// now you can call it without providing `thing` as the context every time like wit apply/call
console.log( thing.foo.bar() );
It's event possible to bind foo.bar
to an instance of Thing, but then every instance of Thing has foo.bar
bound to a shared instance of Thing. I'm not sure if it's a good idea, but it kind of works:
function Thing () {
this.val = 1;
}
Thing.prototype.some = function () {
console.log('thing');
};
Thing.prototype.foo = {
bar: function () {
console.log(this.val);
}.bind( new Thing() )
}
var thing = new Thing();
console.log( thing.foo.bar() );
Upvotes: 0
Reputation: 414086
With that setup, the only way to do it is to explicitly pass the object (the "Thing" instance) as a parameter, or use .call()
or .apply()
.
If you instantiate a "Thing":
var thing = new Thing();
then you can get to that "bar" function as thing.foo.bar
. Invoked from that reference:
thing.foo.bar();
the value of this
inside "bar" will be the "foo" object on the prototype. You could however use .call()
:
thing.foo.bar.call(thing);
then this
in the invocation of "bar" will indeed be the instantiated "Thing" object.
It's important to keep in mind that, in JavaScript, setting an object property to a function does not create any kind of special relationship between the object and the function. What matters is the relationship(s) discovered when referring to property values in expressions. It's always dynamic, and while the mechanics of following the prototype chain are somewhat dizzying, the rules for how this
is determined are pretty simple.
Upvotes: 4