在一个类的方法里面打印“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 } };