edit: I think I have seen this problem when using chrome to debug my full application. So, not sure if this is a typescript issue or a VScode issue.
I was about to submit when I thought I should try it using chrome as the debugger instead of VS code. Chrome works as expected, but VS code shows the problem illustrated below.
I distilled the following down from a larger program that was giving me some strange behavior when examining things in the debugger. The program appears to work correctly in terms of what it prints out, but if I run it in VS code or attach to a running process, when inspecting the value of this
inside somePrivateArrowFunc
, I see different results in the debugger than are printed out to the console:
class MyClass {
someField: number = 123;
private somePrivateArrowFunc = () => {
console.log("somePrivateArrowFunc", this);
};
funcRefs = [this.somePrivateArrowFunc];
funcRef = this.somePrivateArrowFunc;
public somePublicRegularFunc() {
console.log("somePublicRegularFunc", this); // debugger sees "this" as instance of MyClass
for (let f of this.funcRefs) {
f(); // debugger sees "this" as the global object inside somePrivateArrowFunc
}
this.funcRefs[0](); // debugger sees "this" as an array containing f inside somePrivateArrowFunc
this.funcRef(); // debugger sees "this" as an instance of MyClass inside somePrivateArrowFunc
}
}
var c:MyClass = new MyClass();
c.somePublicRegularFunc();
The output printed to the console indicates that the value of this
is always an instance of MyClass
, but a breakpoint on that same console.log
line sees 3 different behaviors:
somePublicRegularFunc MyClass {
someField: 123,
somePrivateArrowFunc: [Function (anonymous)],
funcRefs: [ [Function (anonymous)] ],
funcRef: [Function (anonymous)]
}
somePrivateArrowFunc MyClass {
someField: 123,
somePrivateArrowFunc: [Function (anonymous)],
funcRefs: [ [Function (anonymous)] ],
funcRef: [Function (anonymous)]
}
somePrivateArrowFunc MyClass {
someField: 123,
somePrivateArrowFunc: [Function (anonymous)],
funcRefs: [ [Function (anonymous)] ],
funcRef: [Function (anonymous)]
}
somePrivateArrowFunc MyClass {
someField: 123,
somePrivateArrowFunc: [Function (anonymous)],
funcRefs: [ [Function (anonymous)] ],
funcRef: [Function (anonymous)]
}
I got these results using Version 4.6.3 of tsc
and node v16.13.0 (I also saw the same with earlier versions of both).
CodePudding user response:
It seems to me that what you see as this
with the debugger is simply and really NOT the this
that is actually used by your somePrivateArrowFunc
arrow function.
As expected by design, and as confirmed by your console output, this
in the arrow function is easily predictable and always the same: it is the value where the arrow function is expressed. In your case, the arrow function is expressed during the instance initialization, hence it is your instance.
But the this
that you inspect in your debugger is rather the context, i.e. what a normal function
would get as this
. Which, therefore, depends on how you called the function:
f()
: no context,this
is globalfuncRefs[0]()
: context isfuncRefs
, i.e. the arraythis.funcRef()
: context is the same as the callc.somePublicRegularFunc()
, hence isc
, i.e. an instance
If you turn your arrow function into a normal function
, then your console output will reflect the this
that you get in the debugger.
CodePudding user response:
I found that using a newer target language version (es2022 instead of es5 or es6) fixed the problem. The debugger sees the correct value of this in all 3 scenarios.