用于绑定 JS 对象以进行回调的解决方案

Solutions for binding JS objects for callbacks

本文关键字:回调 解决方案 绑定 JS 对象 用于      更新时间:2023-09-26

我发现有这样的代码是很常见的(这是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; 
        });
    }
}