从console.log自定义打印?

dyn*_*eed 2 javascript google-chrome node.js ecmascript-6

假设我有这门课.

class Attribute {
  constructor(name) {
    this.name = name;
  }
}
Run Code Online (Sandbox Code Playgroud)

我创建一个实例并将其记录到控制台以进行调试.

const test = new Attribute('Large');
console.log(test);
Run Code Online (Sandbox Code Playgroud)

如何让它输出特殊格式的字符串,比如{Attribute} Large?我主要关注Chrome支持,但Node和其他浏览器也不错.

Ant*_*ony 7

apsiller 的答案在 Chrome 和 Firefox 中效果很好,但不幸的是,它在 Node 中不起作用。然而,经过一些实验和研究,我找到了一个在 Node.js 中有效的解决方案。

事实证明,Node 的实现console.log有一个内置的自定义点 ,util.inspect.custom因此您所要做的就是使用该符号定义一个方法,该方法返回您想要打印的任何内容。

class Attribute {
  constructor(name) {
    this.name = name;
  }
  [require('util').inspect.custom](){
    return `{Attribute} ${this.name}`;
  }
}
Run Code Online (Sandbox Code Playgroud)


aps*_*ers 6

一个理智的解决方案可能是使用一个字符串化Attribute值的自定义日志记录功能.

但是,如果您对将来需要维护代码的人进行了仇杀,那么满足此问题的技术要求的一种解决方案是让您的类扩展console.log自动序列化为字符串的类型,例如RegExp.当您console.log使用regualar表达式时,Chrome(我假设其他环境)会自动将其序列化为裸RegExp表达式.只需通过提供自定义/.../函数覆盖它应序列化的字符串,您就可以得到您所要求的.

class Attribute extends RegExp {
  constructor(name) {
    super();
    this.name = name;
  }
  toString() {
    return this.name
  }
}
var test = new Attribute('Large');
console.log(test);
Run Code Online (Sandbox Code Playgroud)

这大致等同于回答"如何阻止我的房屋遭受洪水?"的问题.与"把你的房子放在一个巨大的木筏上"而不是"把一些填缝剂放在你的地下室"或"移动到其他地方".一些副作用包括:

  • 您的对象将继承正则表达式属性,如toStringglobal

  • 测试你的对象exec当然是否会返回true,这可能会导致你的对象成为只希望对正则表达式对象进行操作的例程的有效输入

使用进一步的黑暗魔法,您可以通过这样做来解决这些问题

Object.setPrototypeOf(Attribute.prototype, Object.prototype);
Run Code Online (Sandbox Code Playgroud)

在您的instanceof RegExp定义之后立即执行,这将确保您的class对象将仅通过this构造函数运行(从而将其标记为字符串化RexExp输出)但不会继承log.通过混合RexExp.prototypeclass语法,您还可以确保您的代码混乱,每个人都积极地害怕它.