Jquery Typescript";这";类方法内部
我知道这可能是痛苦的基础,但我有一个艰难的时候,我的头围绕着它Jquery Typescript";这";类方法内部,jquery,this,typescript,proxy-classes,Jquery,This,Typescript,Proxy Classes,我知道这可能是痛苦的基础,但我有一个艰难的时候,我的头围绕着它 class Main { constructor() { requestAnimationFrame(this.update); //fine } update(): void { requestAnimationFrame(this.update); //error, because this is window } }
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
}
}
但是来自ActionScript3的背景,我不确定这里发生了什么。抱歉,我不确定Javascript从哪里开始,TypeScript从哪里结束
updateProxy: () => void
而且,我不相信我做得对。我最不想看到的是,我的大多数类都有一个a()函数,需要使用
aProxy()
来访问它,因为我觉得我在两次编写相同的东西?这正常吗?简而言之,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将在幕后指导您:
$.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
}
};
简而言之,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将在幕后指导您:
$.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
}
};
如果您想捕获此,则可以通过箭头函数来捕获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;
}
您可以看到,在生成的JavaScript中,这个在函数调用之外被捕获:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(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;
}
您可以看到,在生成的JavaScript中,这个在函数调用之外被捕获:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(this));
}
}
因此,函数调用中的这个
值(可能是窗口
)将不会被使用
要了解更多信息:如果您这样编写方法,“this”将按您期望的方式处理
class Main
{
constructor()
{
requestAnimationFrame(() => this.update());
}
update(): void
{
requestAnimationFrame(() => this.update());
}
}
另一个选项是将“this”绑定到函数调用:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(this));
}
}
如果您这样编写方法,“this”将按您期望的方式处理
class Main
{
constructor()
{
requestAnimationFrame(() => this.update());
}
update(): void
{
requestAnimationFrame(() => this.update());
}
}
另一个选项是将“this”绑定到函数调用:
var _this = this;
this.prop = 10;
this.func1 = function (arg) {
return arg + " yeah" + _this.prop;
};
class Main
{
constructor()
{
requestAnimationFrame(this.update.bind(this));
}
update(): void
{
requestAnimationFrame(this.update.bind(this));
}
}
参见typescript语言规范第72页
箭头函数表达式
在这个例子中
class Messenger {
message = "Hello World";
start() {
setTimeout(() => alert(this.message), 3000);
}
};
var messenger = new Messenger();
messenger.start();
使用arrow函数表达式会导致回调具有
这与周围的“开始”方法相同。编写回调
作为标准函数表达式,需要手动
安排对此周围环境的访问,例如将其复制到
局部变量:
这是实际生成的Javascript:
class Messenger {
message = "Hello World";
start() {
var _this = this;
setTimeout(function() { alert(_this.message); }, 3000);
}
};
参见typescript语言规范第72页
箭头函数表达式
在这个例子中
class Messenger {
message = "Hello World";
start() {
setTimeout(() => alert(this.message), 3000);
}
};
var messenger = new Messenger();
messenger.start();
使用arrow函数表达式会导致回调具有
这与周围的“开始”方法相同。编写回调
作为标准函数表达式,需要手动
安排对此周围环境的访问,例如将其复制到
局部变量:
这是实际生成的Javascript:
class Messenger {
message = "Hello World";
start() {
var _this = this;
setTimeout(function() { alert(_this.message); }, 3000);
}
};
当您将函数作为回调传递时,问题就会出现。当回调执行时,“this”的值可能已更改为窗口、调用回调的控件或其他内容
确保在向要回调的函数传递引用时始终使用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”,而是使用_this的值。将函数作为回调传递时会出现问题。当回调执行时,“this”的值可能已更改为窗口、调用回调的控件或其他内容
确保在向要回调的函数传递引用时始终使用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);
因为在特定对象引用上调用AdfFrm函数(这是),它不使用调用方的“这个”,而是这个“./P>>P>的值”到了晚会的很晚,但是我认为对于这个问题的未来访问者来说,考虑下面的内容非常重要:
其他答案,包括公认的答案,忽略了一个关键点:
myFunction(){…}
及
myFunction=()=>{…}
不是同一件事,只是后者捕获了这个
第一种语法在原型上创建一个方法,而第二种语法在对象上创建一个属性,该对象的值是一个函数(捕捉this
)。您可以在传输的JavaScript中清楚地看到这一点
待完成:
myFunction=function(){…}
与第二种语法相同,但没有捕获
因此,在大多数情况下,使用箭头语法可以解决绑定到对象的问题,但情况不同,在许多情况下,您确实希望在原型上使用适当的函数,而不是属性
在这些情况下,使用代理或.bind()
实际上是正确的解决方案。(尽管可读性较差。)
更多阅读(主要不是关于打字脚本,而是原则):
晚会很晚了,但我觉得很不方便