从控制台自定义打印.log?



假设我有这个类。

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

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

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

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

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

但是,如果您对将来需要维护代码的人有仇,满足此问题技术要求的一种解决方案是让您的类扩展一个console.log自动序列化为字符串的类型,例如RegExp。当您console.logRegExp实例时,Chrome(可能还有其他环境)会自动将其序列化为其裸/.../表达式。只需通过提供自定义toString函数来覆盖它应该序列化为的字符串,您就得到了您所要求的内容。

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

这大致相当于用"把你的房子放在一个巨大的木筏上"而不是"在你的地下室放一些填缝剂"或"搬到其他地方"来回答"我如何阻止我的房子被洪水淹没?"这个问题。一些副作用包括:

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

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

使用进一步的黑魔法,你可以通过做

Object.setPrototypeOf(Attribute.prototype, Object.prototype);

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

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}`;
}
}
class Attribute {
constructor(name) {
this.name = name;
}
toString(){//simply set the to String method?
return "{Attribute} "+this.name;
}
}

作为控制台.log不会调用字符串,您要么执行以下操作:

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

或者您创建自己的日志记录函数

最新更新