class Test {
x = 0;
t2: T2;
constructor() {
this.t2 = new T2(this.display);
}
display() {
console.log(this.x);
}
}
class T2 {
constructor(private display: any) {
}
print() {
this.display();
}
}
let t = new Test();
t.t2.print();
When I run the above code it prints undefined
instead 0
, can anyone please help me out with an explanation ? Thank you.
CodePudding user response:
This is not related to TypeScript per se, but is rather a consequence of how this
works in JavaScript. There are a variety of rules around how this
context changes under various circumstances, you can read more about that here.
Here, the value of this
is determined by the receiver of the print
method, which is in this case the object t.t2
. This means inside the print
method, this
is referring to an instance of the T2
class.
The print method then calls this.display()
where again, the value of this
is determined by the receiver. Since the receiver this time is just this
again, it transitively carries over from the prior print
call and is still the t.t2
object.
And finally, since now we know that the this
when you try to execute console.log(this.x)
is actually the T2
instance, we note that the T2
instance does not have a property x
and therefore we get undefined
as expected.
Here is a code snippet demonstrating the this
chain. Note how you can change the receiver of the print
method and how that also changes the value of this
within the method.
class Test {
constructor() {
this.x = 0
this.t2 = new T2(this.display);
}
display() {
console.log("Does this in 'display' equal 't.t2'?:", this === t.t2)
console.log(this.x);
}
}
class T2 {
constructor(display) {
this.display = display
}
print() {
console.log("Does this in 'print' equal 't.t2'?:", this === t.t2);
this.display();
}
}
let t = new Test();
t.t2.print();
// And note you can change the `this` by changing the recieving object:
console.log("Swapping reciever!")
t.print = t.t2.print;
t.print();