Basically, I have the following TypeScript code:
export class ClassA {
method1() {
this.method2(new ClassB().method3);
}
method2(functionReference: () => void) {
functionReference();
}
}
export class ClassB {
method3() {
this.method4();
}
method4() {
console.log("method4 invoked");
}
}
Being more familiar with other OO programming languages (Java, C#, C ), I would expect that running new A().method1();
would eventually cause method4
in ClassB
to be invoked. Instead I run into the problem, that this
is undefined when method3
is eventually run and the execution fails:
TypeError: Cannot read properties of undefined (reading 'method4')
I am aware of all the trickery needed to get this
to work in JavaScript, but I had hoped for the behaviour to be more intuitive in TypeScript. As long as method3
is a non-static method, I would expect to be able to reference this
in the method, no matter from where the method is invoked.
Is there a not too cumbersome pattern available in TypeScript allowing me to use non-static methods as callback functions like I am trying to do here, or is it only possible to use static methods? The latter does not really sound correct, because if it had been so, I would expect the compiler to fail on this.method2(new ClassB().method3)
where I try to pass a non-static method as a function reference.
CodePudding user response:
In javascript the class methods are not bind to its scope when you call them through a reference.
Your code will work correctly if you bind the function to the instance, or if you wrap the call in a function.
Some examples of how you could rewrite the method1 in class ClassA to make things work.
Binding the context to the function:
method1() {
const instance = new ClassB();
this.method2(instance.method3.bind(instance));
}
Wrapping the call:
method1() {
this.method2(()=>new ClassB().method3());
}
CodePudding user response:
You can define the method whose reference you want to pass as a class property
class ClassB {
method3 = () => {
this.method4();
}
method4() {
console.log("method4 invoked");
}
}
this way it will be defined as arrow function upon initialization and the this
reference will be preserved