繁体   English   中英

为什么在超级构造函数的调用中不能在箭头函数中使用“ this”?

[英]Why can't I use “this” in an arrow function in a call to the super constructor?

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

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 )之前的子类中是不允许的,因为在this之前肯定不存在(父类可以返回另一个对象代替this )。 此ES6类限制由规范强制执行。

作为参考状态,

如果子类中存在构造函数,则需要在使用“ 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的问题,并在此答案中进行了描述,建议的解决方案是:

DeferredPromise.prototype.constructor = Promise;

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

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

组成继承就是这种情况。 延迟模式不需要扩展promise类,这样做没有明显的好处。 一个实现可以很简单:

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM