在一个类的方法里面打印“this”

我知道这可能是痛苦的基本的,但我有一个艰难的时间包裹着我的头。

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在哪里开始,TypeScript结束。

 updateProxy: () => void 

而且,我不相信我是这样做的。 我想要的最后一件事是我的类的大部分都有aa()函数,需要使用aProxy()来访问,因为我觉得我写了两次相同的东西? 这是正常的吗?

如果你想this捕获的TypeScript方式做到这一点是通过箭头function。 引用安德斯:

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; } 

在TypeScript Playground中查看

您可以看到,在生成的JavaScript中, this是在函数调用之外捕获的:

 var _this = this; this.prop = 10; this.func1 = function (arg) { return arg + " yeah" + _this.prop; }; 

所以this函数调用(这可能是window )内的值不会被使用。

要了解更多信息: “在TypeScript中了解this ”(4:05) – YouTube

如果你这样写下你的方法,那么“这个”就会像你期望的那样对待。

 class Main { constructor() { requestAnimationFrame(() => this.update()); } update(): void { requestAnimationFrame(() => this.update()); } } 

另一个select是将“this”绑定到函数调用:

 class Main { constructor() { requestAnimationFrame(this.update.bind(this)); } update(): void { requestAnimationFrame(this.update.bind(this)); } } 

将函数作为callback函数传递时,会出现问题。 在callback执行的时候,“this”的值可能已经改变到了Window,调用callback的控件,或者其他的东西。

确保在传递函数的引用时,总是使用lambdaexpression式来callback。 例如

 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”,而是使用_this的值。

请参阅打印机语言规范的第72页https://github.com/Microsoft/TypeScript/blob/master/doc/TypeScript%20Language%20Specification.pdf?raw=true

箭头函数expression式

在这个例子中

 class Messenger { message = "Hello World"; start() { setTimeout(() => alert(this.message), 3000); } }; var messenger = new Messenger(); messenger.start(); 

使用箭头函数expression式会导致callback与周围的“开始”方法具有相同的效果。 把callback函数写成一个标准的函数expression式,就需要手动安排对周围环境的访问,例如把它复制到一个局部variables中:

这是实际生成的Javascript:

 class Messenger { message = "Hello World"; start() { var _this = this; setTimeout(function() { alert(_this.message); }, 3000); } }; 

简而言之,这个关键字总是对调用该函数的对象有一个引用。

在Javascript中,因为函数只是variables,所以可以传递它们。

例:

 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将会引导你:

 $.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 } };