Cla*_*ark 75 jquery proxy-classes this typescript
我知道这可能是基本的痛苦,但我很难绕过它.
class Main
{
constructor()
{
requestAnimationFrame(this.update); //fine
}
update(): void
{
requestAnimationFrame(this.update); //error, because this is window
}
}
Run Code Online (Sandbox Code Playgroud)
似乎我需要一个代理,所以让我们说使用Jquery
class Main
{
constructor()
{
this.updateProxy = $.proxy(this.update, this);
requestAnimationFrame(this.updateProxy); //fine
}
updateProxy: () => void
update(): void
{
requestAnimationFrame(this.updateProxy); //fine
}
}
Run Code Online (Sandbox Code Playgroud)
但是来自Actionscript 3的背景,我不确定这里发生了什么.抱歉,我不确定Javascript的开始位置和TypeScript结束.
updateProxy: () => void
Run Code Online (Sandbox Code Playgroud)
而且,我不相信我这样做是对的.我想要的最后一件事是我的班级大部分都有aa()函数需要访问,aProxy()因为我觉得我写两次相同的东西?这是正常的吗?
bas*_*rat 105
如果你想要this捕获TypeScript的方法是通过箭头函数.引用安德斯:
在
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;
}
Run Code Online (Sandbox Code Playgroud)
您可以看到在生成的JavaScript this中,在函数调用之外捕获:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
Run Code Online (Sandbox Code Playgroud)
所以this函数调用中的值(可能是window)将不会被使用.
要了解更多信息:" this在TypeScript中理解"(4:05) - YouTube
joe*_*net 17
如果你写这样的方法,'this'将按你期望的方式对待.
class Main
{
constructor()
{
requestAnimationFrame(() => this.update());
}
update(): void
{
requestAnimationFrame(() => this.update());
}
}
Run Code Online (Sandbox Code Playgroud)
另一种选择是将'this'绑定到函数调用:
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(this));
}
}
Run Code Online (Sandbox Code Playgroud)
聚会已经很晚了,但我认为对于这个问题的未来访问者来说,考虑以下几点非常重要:
其他答案,包括已接受的答案,都忽略了一个关键点:
myFunction() { ... }
Run Code Online (Sandbox Code Playgroud)
和
myFunction = () => { ... }
Run Code Online (Sandbox Code Playgroud)
不是同一件事“除了后者捕获的例外this”。
第一个语法在原型上创建一个方法,而第二个语法在值为函数的对象上创建一个属性(也恰好捕获this)。您可以在转译的 JavaScript 中清楚地看到这一点。
完整:
myFunction = function() { ... }
Run Code Online (Sandbox Code Playgroud)
与第二种语法相同,但没有捕获。
因此,在大多数情况下使用箭头语法可以解决绑定到对象的问题,但它并不相同,并且在很多情况下您确实希望在原型上使用适当的函数而不是属性。
在这些情况下,使用代理.bind()实际上是正确的解决方案。(尽管可读性受到影响。)
更多阅读内容请参见此处(主要不是关于 TypeScript,但原则是成立的):
https://ponyfoo.com/articles/binding-methods-to-class-instance-objects
参见打字稿语言规范的第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();
Run Code Online (Sandbox Code Playgroud)
使用箭头函数表达式会使回调与周围的“开始”方法具有相同的含义。将回调写为标准函数表达式,必须手动安排对其周围环境的访问,例如,将其复制到局部变量中:
这是实际生成的Javascript:
class Messenger {
message = "Hello World";
start() {
var _this = this;
setTimeout(function() { alert(_this.message); }, 3000);
}
};
Run Code Online (Sandbox Code Playgroud)
当您将函数作为回调传递时,就会出现问题。当回调执行时,“this”的值可能已更改为窗口、调用回调的控件或其他内容。
确保在传递对要回调的函数的引用时始终使用 lambda 表达式。例如
public addFile(file) {
this.files.push(file);
}
//Not like this
someObject.doSomething(addFile);
//but instead, like this
someObject.doSomething( (file) => addFile(file) );
Run Code Online (Sandbox Code Playgroud)
这编译成类似的东西
this.addFile(file) {
this.files.push(file);
}
var _this = this;
someObject.doSomething(_this.addFile);
Run Code Online (Sandbox Code Playgroud)
因为 addFile 函数是在特定对象引用 (_this) 上调用的,所以它不使用调用者的“this”,而是使用 _this 的值。