Reputation: 562
In JavaScript, if I attach a function to an object's prototype, within that function, this
refers to the current instance of the object. For example:
function RageFest(inquiry) {
this.inquiry = inquiry;
}
RageFest.prototype.myFunction0 = function () {
console.log(this.inquiry);
};
new RageFest("you mad, bro?").myFunction0(); // prints "you mad, bro?"
Running this in Node prints you mad, bro?
to the terminal, as expected.
Now, here's where I run into trouble: suppose I want to introduce a second level of organization (maybe because RageFest
has lots of methods attached to it, and I want to organize them).
RageFest.prototype.myObject = {
myFunction1: function () { console.log(this.inquiry); },
myFunction2: function () { console.log(this.inquiry); }.bind(this),
myFunction3: function () { console.log(this.inquiry); }.bind(RageFest)
};
var ragefest = new RageFest("you mad, bro?");
ragefest.myObject.myFunction1(); // undefined
ragefest.myObject.myFunction2(); // undefined
ragefest.myObject.myFunction3(); // undefined
None of these work! If I make myObject's three functions log this
(rather than this.inquiry
), it shows that:
this
refers to myObject
this
refers to the global objectthis
refers to the RageFest constructorHowever, binding the instance (rather than the constructor) works:
RageFest.prototype.myObject.myFunction4 = function () {
console.log(this.inquiry);
}.bind(ragefest);
ragefest.myObject.myFunction4(); // prints "you mad, bro?"
This prints out you mad, bro?
, as desired, but it feels like a terrible hack. It also requires me to create an instance of RageFest
beforehand, which is annoying.
So, my question is, is there a way of achieving the effect I want -- functions inside a nested object that have access to the current instance using the this
keyword -- without resorting to this hackery?
Upvotes: 2
Views: 1214
Reputation: 801
Instead of creating nested object creating getter will be helpful, which will be called in constructor function and assigned to an object property.
function RageFest(inquiry) {
this.inquiry = inquiry;
this.myObject = this.getMyObject();
}
RageFest.prototype.myFunction0 = function () {
console.log(this.inquiry);
};
RageFest.prototype.getMyObject = function(){
var that = this;
return {
myFunction1: function () { console.log(that.inquiry); },
myFunction2: function () { console.log(that.inquiry); }
}
};
var ragefest = new RageFest("you mad, bro?");
ragefest.myObject.myFunction1();
ragefest.myObject.myFunction2();
Upvotes: 3