Reputation: 66
I need to create an object within array of functions which should be called inside of object. but myObj.myFunctions is always undefined inside of my object after creation.
here is my example code
var myObj = {
myValue:"My Callback function has been Called",
myFunctions: [this.myCallback,this.myCallback2],
init: function(){
//I need to call this.myFunctions[0...etc] as callback
//this.myFunctions[0]() //<-- Here is the error
console.log(this.myFunctions); //<-- always undefined
},
myCallback:function(){
console.log(this.myValue);
},
myCallback2:function(){
console.log(this.myValue+" Second Callback");
}
}
var createObject = Object.create(myObj);
createObject.init();
any idea how could I create array of functions as property of main object? Thanks
Upvotes: 1
Views: 4199
Reputation: 8269
You need to Create a function inside your myFunctions and return those array of callbacks:
Method #1
var myObj = {
myValue:"My Callback function has been Called",
myFunctions: function () { // Assign a function and return those array of callbacks
return [this.myCallback,this.myCallback2];
},
init: function(){
return this.myFunctions();
},
myCallback:function(){
console.log(this.myValue);
},
myCallback2:function(){
console.log(this.myValue+" Second Callback");
}
};
var createObject = Object.create(myObj);
var functions = createObject.init();
console.log(functions); // [f(), f()]
// f for short-term of 'function'
Method #2 - Using direct () function call is already supported for cleaner code
var myObj = {
myValue:"My Callback function has been Called",
myFunctions() {
return [this.myCallback, this.myCallback2]
},
init() {
return this.myFunctions();
},
myCallback(){
console.log(this.myValue);
},
myCallback2(){
console.log(this.myValue+" Second Callback");
}
};
Method #3 - Using ES6 Spread Operator and Replace 'this' to 'myObj'
const myObj = {
myValue:"My Callback function has been Called",
myFunctions: () => [myObj.myCallback, myObj.myCallback2],
init: () => myObj.myFunctions(),
myCallback: () => console.log(myObj.myValue),
myCallback2: () => console.log(`${myObj.myValue} Second Callback`)
};
Upvotes: 2
Reputation: 18515
The concept which you are fighting against is the meaning of this
when you call/host your callback functions inside of the array. When done that way this
becomes the array
and thus you do not get the expected result. One way to get that result could be using call
and transform your object so it can be instantiated like this:
var myObj = function() {
this.myValue = "My Callback function has been Called",
this.init = function() {
this.myFunctions[0].call(this) // <-- pass the proper `this`
this.myFunctions[1].call(this)
},
this.myCallback = function() {
console.log(this.myValue);
},
this.myCallback2 = function() {
console.log(this.myValue + " Second Callback");
},
this.myFunctions = [this.myCallback, this.myCallback2]
}
var createObject = new myObj()
createObject.init();
Another way would be via bind
but that is hardly recommended these days so I would skip it and head towards a recommendation which I think you should consider:
class MyObj {
constructor(val) {
this.myValue = val;
}
myCallback() {
console.log(this.myValue + " - First Callback");
}
myCallback2() {
console.log(this.myValue + " - Second Callback");
}
get myCallbacks() {
return ['myCallback', 'myCallback2']
}
init() {
this[this.myCallbacks[0]]() // <-- no issues with `this` anymore
this[this.myCallbacks[1]]()
}
}
var createObject = new MyObj('foo')
createObject.init();
Host your callback as string keys
in your myCallbacks
array in your class. That way you can call them via property accessor and not worry about the this
context since at this time it would be the one you expect - the class.
Upvotes: 1