【问题标题】:Visual Studio shows wrong value for `this` in TypeScript [duplicate]Visual Studio 在 TypeScript 中显示 `this` 的错误值 [重复]
【发布时间】:2015-07-15 09:37:12
【问题描述】:

考虑以下代码:

class Person{
    firstname = ko.observable<string>();
    lastname: ko.observable<string>();
    fullname = ko.computed(()=>{

        // Breakpoint here
        return this.firstname() + ' ' + this.lastname();

    });

当我使用 Visual Studio 2013 进行调试时,如果我设置断点并使用监视或即时窗口查看 this 的值,则表明该值是 window 而不是人员实例。因此,它会为this.firstname 显示undefined

检查转换后的 JavaScript 代码我发现我应该检查 _this 的值而不是 this

虽然代码运行没有错误,但是我浪费了很多时间来理解this变量的真实值可以通过_this获得。

问题我在使用类属性时是否有错误导致this 值中出现这种误导性值?或者它只是一个错误?或者可能是出于某种原因设计的?

【问题讨论】:

  • @Bergi 这个问题不是重复的问题。这个问题是 4 年前提出的,而您提到的问题是 3 年前提出的。因此,如果有重复的问题,则该问题应视为重复!
  • 是的,它们是相互重复的。你没有做错任何事,你的问题被关闭并不意味着对你有任何伤害。我选择了另一个问题作为规范问题,因为它没有特定于淘汰赛的代码。

标签: javascript visual-studio visual-studio-2013 typescript typescript1.4


【解决方案1】:

由于“this”关键字在 javascript 中的工作方式,Typescript 会为您创建“_this”别名。这是设计使然,当您知道它是如何工作时,它会很棒。

你的例子:

class Person {
    firstname = ko.observable<string>();
    lastname: ko.observable<string>();
    fullname = ko.computed(
        () => {
            // Breakpoint here
            return this.firstname() + ' ' + this.lastname();
    });
}

编译为:

var Person = (function () {
    function Person() {
        var _this = this;
        this.firstname = ko.observable();
        this.lastname = ();
        this.fullname = ko.computed(function () {
            // Breakpoint here
            return _this.firstname() + ' ' + _this.lastname();
        });
    }
    return Person;
})();

这表明(正如您所提到的)您的全名计算函数中的“this”已被编译为“_this”。您的调试问题是 Visual Studio 正在调试已编译的 javascript。在 javascript 中,函数内部的“this”表示其他含义,请在 javascript here 中阅读有关“this”的更多信息。

Typescript 在您使用 lambda 函数时创建一个 _this 引用,即:

class foo {

    something: string = "some string";

    foo1 = () => { this.something }
    foo2() { this.something }
}

编译为:

var foo = (function () {
    function foo() {
        var _this = this;
        this.something = "some string";
        this.foo1 = function () { _this.something; };
    }
    foo.prototype.foo2 = function () { this.something; };
    return foo;
})();

如果在 typescript 中正确使用 lambda 函数,则可以解决 javascript 中的“this”地狱。在大多数情况下,您不需要考虑何时使用 lambda 或函数,但在某些情况下您会这样做。更多关于 lambda 函数的信息可以在here找到。

使用这个的简短答案是在使用 lambdas 时检查 _this 直到它被修复。 它有一个未解决的问题:https://typescript.codeplex.com/workitem/1655

【讨论】:

  • 问题是 Visual Studio 应该为 this 显示正确的值。等效 JavaScript 中的 this 与 TypeScript 中的 this 具有不同的含义。在 JavaScript 中有 this_this 具有不同的值。但在原来的 TypeScript 中,只有一个 this 相当于 JavaScript 代码中的 _this 值。
  • 确实,这是一个比其他任何问题都重要的工具问题。这似乎是我们必须忍受一段时间的事情,因为这个问题已经知道并且有一段时间没有解决。 typescript.codeplex.com/workitem/1655
  • 因为 _this 我使用 Visual Studio“Watch”窗口并将“_this”添加到窗口中,这样我就可以看到设置了哪些值
  • @Nypan screaaaaam...如您所愿!
  • 看起来the issue 仍然打开...
【解决方案2】:

好吧,您只是偶然发现了 JavaScript 的麻烦之一。 “这让我发疯,但我不知道这是指什么”。所以这不是错误,这是设计使然。长话短说,JavaScript 根据上下文重新调整this 的范围。在您使用 d3(用于事件回调)或 angular 或 knout 等库时,这尤其成问题。这个问题在使用 TypeScript 时变得更加明显,因为你必须在任何地方使用this。 您可以在 the mozilla developer network 上找到更多关于使用 this 的文档。

为了规避您的问题,最简单的解决方案是在输入回调之前保留对原始this 的引用,并在内部使用局部变量,即:

class Person{
  firstname = ko.observable<string>();
  lastname: ko.observable<string>();
  var self = this;
  fullname = ko.computed(()=>{

    // Breakpoint here
    return self.firstname() + ' ' + self.lastname();

  });

我建议您采用这种习惯以避免将来出现问题,并且是 JavaScript 中的一种好习惯。

【讨论】:

  • 我不认为在 TypeScript 中定义自己的自我引用是一种好习惯,因为 typescript 会为您执行此操作,您只需要知道何时以及如何使用 lambda,“this”的问题就会消失.请在下面查看我的答案。
  • 我对 TypeScript 中 this 的 REAL 值没有任何问题,因为它是真的。唯一的问题是调试器显示不正确。
  • 这是最近的改进吗?我选择了selfway,因为我在使用this 时遇到了一些问题。很高兴知道,感谢您提供的信息。
猜你喜欢
  • 1970-01-01
  • 2017-05-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-09-07
  • 2018-03-19
  • 2017-07-28
相关资源
最近更新 更多