打字稿“这个”内的一类方法(Typescript “this” inside a class met

2019-08-31 20:26发布

我知道这可能是痛苦的基础,但我有一个艰难的时间环绕我的头周围。

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