我发现有这样的代码是很常见的(这是TypeScript,但等效的JS相当明显,这确实是一个JS问题,尽管TS可以解决):
class Foo {
someField;
someMethod() {
doSomethingTakingACallback(function() {
this.someField; // Fails because `this` is not the instance of `Foo`
});
}
}
当然,解决方案是像这样使用Function.bind()
:
someMethod() {
doSomethingTakingACallback(function() {
this.someField; // Works as expected
}.bind(this));
}
现在的问题是我有必须经常访问对象实例的回调(即,我需要在许多回调上调用bind(this)
)。我现在在由此产生的错误上浪费的时间比我想承认的要多。还有其他选择吗?我是否错过了一些更简单的方法?有什么理由认为这是默认行为,而不是我们从调用bind(this)
中获得的函数?
我知道的一种解决方案是做一些类似var me = this
的事情,然后调用me.someField
(等)。当我有很多回调或嵌套回调时,它看起来更好一些。虽然那时我失去了this
的标志性,但我觉得这使得成员所在的位置(在我正在编写的类上)最清楚。
Typescript 和 ES6/ES2015 都支持"胖箭头函数"语法,它允许您使用this
,就像在大多数其他语言中所做的那样 - 引用类实例对象。
例如
someMethod() {
doSomethingTakingACallback(() => {
this.someField;
});
}
这将编译为以下代码:
Foo.prototype.someMethod = function () {
var _this = this;
doSomethingTakingACallback(function () {
_this.someField;
});
};
ES6 箭头函数保持周围作用域的this
,因此不需要绑定。
ES7 将(可能)具有 :: 绑定运算符
将this
赋值给回调方法之外的另一个变量并使用它。
class Foo {
someField : any;
someMethod() {
var that = this;
doSomethingTakingACallback(function () {
// use that.someField;
});
}
}