【问题标题】:How to use ES6 super to call parent method in child constructor?如何在子构造函数中使用 ES6 super 调用父方法?
【发布时间】:2018-03-17 08:44:54
【问题描述】:

情况:

我正在扩展 Node.js (v. 8.4.0) 带有附加属性(时间戳、id)的错误对象,然后扩展此对象以获得更精细的错误处理。

class MyError extends Error {
  constructor (msg) {
    super(msg);
    this.id = uuid();
    this.timestamp = Date.now();
    // I reckon this can be replaced by this.init(this) ?
    this.name = this.constructor.name;
    Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
  }

  init (self) {
    self.name = self.constructor.name;
    Error.captureStackTrace && Error.captureStackTrace(self, self.constructor);
  }
}

我希望不会在子错误中重复Error.captureStackTracethis.name 调用。所以我创建了一个 init 函数,我在孩子中使用这样的函数:

class GranularError extends MyError {
  constructor (msg) {
    super(msg);
    this.type = "error";
    this.status = 500;
    this.code = "internalServerError";
    super.init(this);
  }
}

GranularError 然后将再次扩展以获取 MoreGranularError 等。这就是为什么我想让它保持 DRY。

问题:

当 GranularError 或 MoreGranularError 被抛出时,它会失败并显示一个

TypeError: (intermediate value).init is not a function

我主要阅读了以下资料,但我无法将它们应用于问题。任何帮助表示赞赏。

Call parent function which is being overridden by child during constructor chain in JavaScript(ES6)

Parent constructor call overridden functions before all child constructors are finished

http://2ality.com/2015/02/es6-classes-final.html#referring_to_super-properties_in_methods

【问题讨论】:

  • 您的代码似乎在 Chrome (jsfiddle.net/Lrfxum4a) 中运行顺畅。你用的是什么环境? (我猜是Node,基于uuid?什么版本?)
  • 是的,它是 Node 8.4.0。我已经将它添加到开头。感谢您的评论。它似乎在 Chrome 上运行良好,这确实很奇怪。

标签: javascript node.js ecmascript-6 super es6-class


【解决方案1】:

我不知道你得到这个错误是什么,但没有必要创建一个init 函数。 this.nameError.captureStack 的内容也将在子实例中起作用,因为 this 指的是子实例。

换句话说,您正在尝试解决一个不存在的问题。

class MyError extends Error {
  constructor (msg) {
    super(msg);
    this.id = Math.random();
    this.timestamp = Date.now();
    this.name = this.constructor.name;
    Error.captureStackTrace && Error.captureStackTrace(this, this.constructor);
  }
}
class GranularError extends MyError {
  constructor (msg) {
    super(msg);
    this.type = "error";
    this.status = 500;
    this.code = "internalServerError";
  }
}

console.dir(new GranularError("this is the error message"));

【讨论】:

  • 这是我尝试实现 init 函数之前代码的样子。我一定在其他地方遇到了错误,并且在尝试实现 init() 时,我必须修复它。现在可以了。谢谢。
  • 或者更好的是,将this.constructor替换为new.target
  • @Bergi 在上述情况下使用 new.target 是否有实际好处,或者它只是街区中最酷的新手?
  • @OndraUrban 我猜两者都是 :-) 它甚至在super() 调用之前就可以工作(因为它不使用this),并且没有人可以弄乱.constructor 属性(尽管这是诚然,class 语法的问题比以前少了)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-01-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多