Reputation: 3
I am currently working on a project where I want to deference an array of functions (function references) and excecute the function.
This does only work, if I don't call another class method within the function. Otherwise I get "Uncaught TypeError" and I can't figure out how to solve this error.
Here's my code sample 'working' the same way my original project does: After calling function2 the engine cannot find this.log...
Do you have ideas? Thank you very much in advance.
KR, Robert
class ArrayWithFunctions {
constructor() {
this.functionTable = [
this.function1,
this.function2,
];
}
execute(index) {
return (this.functionTable[index])();
}
log(chars) {
console.log(chars);
}
function1() {
console.log('I am Function 1.');
}
function2() {
this.log('I am Function 2.');
}
}
let example = new ArrayWithFunctions();
example.execute(0);
example.execute(1);
Upvotes: 0
Views: 859
Reputation: 1407
This is an example of Javascript's execution contexts in action. In this situation, to avoid losing the correct reference to the class, you can bind the functions when putting them inside the array, or initialize them as arrow functions:
Example 1: Bind them in the constructor:
constructor() {
this.functionTable = [
this.function1.bind(this),
this.function2.bind(this),
];
}
Example 2: Create them as arrow functions:
class ArrayWithFunctions {
// ...
function1 = () => {
console.log('I am Function 1.');
}
function2 = () => {
this.log('I am Function 2.');
}
}
Upvotes: 1
Reputation: 816364
Related: How to access the correct `this` inside a callback (and you might also want to take a look at How does the "this" keyword work?).
In this case you can simply set the correct this
value by calling the function with .call
:
return this.functionTable[index].call(this);
Upvotes: 0
Reputation: 8165
You can use arrow functions to dodge scoping issues:
function2 = () => {
this.log('I am function 2.');
}
Upvotes: 0