请考虑以下代码:
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
而不是该人实例。因此,它会显示undefined
的{{1}}。
检查已转换的JavaScript代码我发现我应该检查this.firstname
而不是_this
的值。
虽然代码运行没有错误,但是我浪费了大量时间来理解this
变量的真正价值可通过this
获得。
问题我在使用类属性时导致错误导致_this
值误导?或者它只是一个错误?或者也许是出于某种原因设计的?
答案 0 :(得分:9)
由于&#34;这个&#34;关键字适用于javascript Typescript创建&#34; _this&#34;你的别名。这是设计的,当你知道它是如何工作的时候很棒。
你的例子:
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;
})();
这表明(正如你所提到的)&#34;这个&#34;在你的全名计算函数已被编译为&#34; _this&#34;。您调试的问题是Visual Studio正在调试已编译的JavaScript。在javascript&#34;这个&#34;在函数内部意味着别的东西,阅读更多关于&#34;这个&#34;在javascript here。
当你使用lambda函数时,Typescript会创建一个_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;
})();
如果正确使用,打字稿中的lambda函数可以解决&#34; this&#34;来自javascript的地狱。在大多数情况下,您不需要考虑何时使用lambda或函数,但在某些情况下,您可以这样做。有关lambda函数的更多信息可以在here找到。
处理这个问题的简单答案是在使用lambdas时检查_this,直到它被修复为止。 有一个未解决的问题:https://typescript.codeplex.com/workitem/1655。
答案 1 :(得分:2)
嗯,你只是偶然发现了JavaScript的麻烦之一。 “这让我发疯,但我不知道这指的是什么”。所以这不是一个错误,这是设计的。长话短说,JavaScript根据上下文重新调整this
。在使用诸如d3(用于事件回调)或角度或者敲除的库时,这尤其成问题。使用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练习。