我知道这可能是痛苦的基础,但我有一个艰难的时间环绕我的头周围。
class Main
{
constructor()
{
requestAnimationFrame(this.update); //fine
}
update(): void
{
requestAnimationFrame(this.update); //error, because this is window
}
}
这似乎是说我需要一个代理的情况下,因此,可以说使用jQuery
class Main
{
constructor()
{
this.updateProxy = $.proxy(this.update, this);
requestAnimationFrame(this.updateProxy); //fine
}
updateProxy: () => void
update(): void
{
requestAnimationFrame(this.updateProxy); //fine
}
}
但是从ActionScript 3的背景来了,我真的不知道这里发生了什么。 对不起,我不知道从哪里开始的Javascript和打字稿结束。
updateProxy: () => void
而且,我不相信我是这样做的权利。 我想的最后一件事是我最有AA级()函数,它需要与访问的aProxy()
因为我觉得我写同样的事情两次? 它是正常的吗?
Answer 1:
如果你想要this
拍摄这样的打字稿方式是通过箭头的功能。 引述安德斯:
在this
箭头功能的词法范围
这是我喜欢用这个对我有利的方式:
class test{
// Use arrow functions
func1=(arg:string)=>{
return arg+" yeah" + this.prop;
}
func2=(arg:number)=>{
return arg+10 + this.prop;
}
// some property on this
prop = 10;
}
查看本了打字稿游乐场
你可以看到,在生成的JavaScript this
是在函数调用外拍摄的:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
所以this
函数调用(可能是内在价值window
)将不会被使用。
要了解更多信息: “了解this
在打字稿”(4:05) - YouTube的
Answer 2:
如果你写你的方法是这样,“这”将被视为您所期望的方式。
class Main
{
constructor()
{
requestAnimationFrame(() => this.update());
}
update(): void
{
requestAnimationFrame(() => this.update());
}
}
另一种选择是绑定“这个”的函数调用:
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(this));
}
}
Answer 3:
当你将一个函数作为回调,就会出现问题。 由当时的回调已执行的“本”可能已经改变了窗口,控件调用回调,还是其他什么东西的价值。
确保你总是在你传递给函数的引用要回调的点使用lambda表达式。 例如
public addFile(file) {
this.files.push(file);
}
//Not like this
someObject.doSomething(addFile);
//but instead, like this
someObject.doSomething( (file) => addFile(file) );
这编译成类似
this.addFile(file) {
this.files.push(file);
}
var _this = this;
someObject.doSomething(_this.addFile);
因为addFile函数被调用上的特定对象引用(_this)它不使用的“本”的调用器,但代替_this值。
Answer 4:
见打字稿语言规范的72页https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true
箭头函数表达式
在这个例子中
class Messenger {
message = "Hello World";
start() {
setTimeout(() => alert(this.message), 3000);
}
};
var messenger = new Messenger();
messenger.start();
使用箭头函数表达式使回调具有相同的这个作为周边“开始”方法。 写回调当它变得必要通过复制到一个局部变量来手动排列访问到周围此,例如一个标准的函数表达式:
这是实际生成的JavaScript:
class Messenger {
message = "Hello World";
start() {
var _this = this;
setTimeout(function() { alert(_this.message); }, 3000);
}
};
Answer 5:
总之,this关键字总是要调用该函数的对象的引用。
在Javascript中,因为函数只是变量,你可以通过他们周围。
例:
var x = {
localvar: 5,
test: function(){
alert(this.localvar);
}
};
x.test() // outputs 5
var y;
y.somemethod = x.test; // assign the function test from x to the 'property' somemethod on y
y.test(); // outputs undefined, this now points to y and y has no localvar
y.localvar = "super dooper string";
y.test(); // outputs super dooper string
当你使用jQuery如下:
$.proxy(this.update, this);
你在做什么是压倒一切的这方面。 在幕后jQuery将guive你:
$.proxy = function(fnc, scope){
return function(){
return fnc.apply(scope); // apply is a method on a function that calls that function with a given this value
}
};
Answer 6:
非常迟到了,但我认为这是对这个问题的未来游客考虑以下几点非常重要:
其他答案,包括接受一个,错过了关键点:
myFunction() { ... }
和
myFunction = () => { ... }
是不一样的东西“不同的是后者捕捉this
”。
所述第一语法上创建的原型的方法,而所述第二语法创建对象上的属性卫生组织值是一个函数(即也恰好捕获this
)。 您可以在transpiled的JavaScript清楚地看到这一点。
要完成:
myFunction = function() { ... }
将是相同ALS第二语法,但没有捕获。
因此, 在大多数情况下,使用箭头语法将解决您的结合对象的问题,但它是不一样的,有很多情况下你想对原型的属性代替正常功能。
在使用代理或这些情况.bind()
实际上是正确的解决方案。 (虽然痛苦可读性。)
更多阅读这里(主要不打字稿,但坚持原则):
https://medium.com/@charpeni/arrow-functions-in-class-properties-might-not-be-as-great-as-we-think-3b3551c440b1
https://ponyfoo.com/articles/binding-methods-to-class-instance-objects
文章来源: Typescript “this” inside a class method