edit:我想我在使用chrome调试我的完整应用程序时看到了这个问题。所以,不确定这是一个typescript问题还是一个VScode问题。
当我想我应该尝试使用chrome作为调试器而不是VS code时,我正要提交。Chrome按预期工作,但VS code显示如下所示的问题。
我从一个较大的程序中提取了下面的代码,这个程序在调试器中检查时会给我一些奇怪的行为。该程序在打印出来的内容方面似乎正确工作,但如果我在VS代码中运行它或附加到正在运行的进程中,当检查somePrivateArrowFunc
内部的this
的值时,我在调试器中看到的结果与打印到控制台的结果不同:
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();
打印到控制台的输出表明this
的值始终是MyClass
的一个实例,但是同一console.log
行的断点看到3个不同的行为:
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)]
}
我使用tsc
的4.6.3版本和节点v16.13.0得到了这些结果(我在这两个版本的早期版本中也看到了相同的结果)。
在我看来,你所看到的this
与调试器是简单的,真的不是你的somePrivateArrowFunc
箭头函数实际使用的this
。
正如设计所期望的那样,并且正如控制台输出所确认的那样,箭头函数中的this
很容易预测并且总是相同的:它是表示的箭头函数的值。在您的例子中,箭头函数是在实例初始化期间表示的,因此它是您的实例。
但是您在调试器中检查的this
是上下文,即正常的function
将获得this
。因此,这取决于您如何调用函数:
f()
: no context,this
是globalfuncRefs[0]()
:上下文是funcRefs
,即数组this.funcRef()
:上下文与调用c.somePublicRegularFunc()
相同,因此是c
,即实例
如果您将箭头函数转换为正常的function
,那么您的控制台输出将反映您在调试器中获得的this
。
我发现使用较新的目标语言版本(es2022而不是es5或es6)解决了这个问题。调试器在所有3种情况下都能看到正确的值。