在VS code下调试typescript程序时' this '不一致



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是global
  • funcRefs[0]():上下文是funcRefs,即数组
  • this.funcRef():上下文与调用c.somePublicRegularFunc()相同,因此是c,即实例

如果您将箭头函数转换为正常的function,那么您的控制台输出将反映您在调试器中获得的this

我发现使用较新的目标语言版本(es2022而不是es5或es6)解决了这个问题。调试器在所有3种情况下都能看到正确的值。

最新更新