从console.log自定义打印?

时间:2017-04-14 17:40:02

标签: javascript node.js google-chrome ecmascript-6

我们说我有这门课。

class Attribute {
  constructor(name) {
    this.name = name;
  }
}

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

const test = new Attribute('Large');
console.log(test);

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

3 个答案:

答案 0 :(得分:5)

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

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

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

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

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

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

使用更深层的魔法,您可以通过

来解决这些问题
Object.setPrototypeOf(Attribute.prototype, Object.prototype);

class定义之后立即执行,这将确保您的this对象只会通过RexExp构造函数运行(从而将其标记为字符串化log输出)但不是从RexExp.prototype继承。通过将classprototype语法混合在一起,您还可以确保代码混乱,并且每个人都非常害怕它。

答案 1 :(得分:2)

class Attribute {
  constructor(name) {
    this.name = name;
  }
  toString(){//simply set the to String method?
    return "{Attribute} "+this.name;
  }
}

由于console.log不调用String,您可以执行以下操作:

const test = new Attribute('Large');
console.log(test+"");

或者您创建自己的日志记录功能

答案 2 :(得分:2)

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

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

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