【问题标题】:Why can't I use "this" in an arrow function in a call to the super constructor?为什么我不能在调用超级构造函数的箭头函数中使用“this”?
【发布时间】:2018-06-15 00:00:36
【问题描述】:

我正在尝试创建一个延迟承诺构造函数,如下所示:

class DeferredPromise extends Promise {
  constructor() {
    super((resolve, reject) => {
      this.resolve = resolve
      this.reject = reject
    })
  }
}

但是,当我尝试使用 new DeferredPromise() 时,我在 Firefox 60.0.01 中收到以下错误

ReferenceError: must call super constructor before using |this| in arrow function in derived class constructor

为什么会出现此错误,我该如何解决?另外,如果有更好的解决方案,请告诉我。

【问题讨论】:

  • 必须在引用this 之前调用super。也不清楚你为什么不只使用Promise.resolve(something)Promise.reject(someError)
  • 仅供参考,如果您只是在寻找一个简单的延迟对象实现,那么这里已经有几个堆栈溢出了。这是一个:Deferred implementation.

标签: javascript class ecmascript-6 arrow-functions


【解决方案1】:

this 在父构造函数调用 (super) 之前不允许在子类中,因为 this 在此之前肯定不存在(父类可以返回另一个对象而不是 this)。此 ES6 类限制由规范强制执行。

正如the reference 所说,

如果子类中存在构造函数,在使用“this”之前需要先调用super()。

如果知道this是在父构造函数调用后才在函数内部使用,则可以放心使用:

class Foo {
  constructor(callback) {
    this.doFoo = callback;
  }
}

class Bar extends Foo {
  constructor() {
    super(() => {
      this.doBar();
    })
  }

  doBar() {}
}

new Bar().doFoo();

否则 this 应该只在父构造函数调用之后被引用:

class DeferredPromise extends Promise {
  constructor() {
    let resolve, reject;

    super((_resolve, _reject) => {
      resolve = _resolve;
      reject = _reject;
    });

    this.resolve = resolve;
    this.reject = reject;
  }
}

这将导致Promise 特有的问题,并在this answer 中描述,建议的解决方案是:

DeferredPromise.prototype.constructor = Promise;

这意味着需要存储 DeferredPromise 实例以访问 resolvereject 方法,它们在链式 Promise 中不可用:

let deferred = new DeferredPromise();
let nonDeferred = deferred.catch(() => {});
// nonDeferred.reject === undefined

composition over inheritance 就是这种情况。延迟模式不需要扩展承诺类,这样做没有明显的好处。实现可以很简单:

class Deferred {
  constructor() {
    this.promise = new Promise((resolve, reject) => {
      this.resolve = resolve;
      this.reject = reject;
    });
  }
}

【讨论】:

    猜你喜欢
    • 2011-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-16
    • 1970-01-01
    • 2021-11-23
    • 1970-01-01
    • 2022-10-17
    相关资源
    最近更新 更多