最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Custom printing from console.log? - Stack Overflow

programmeradmin3浏览0评论

Let's say I have this class.

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

And I create an instance and log it to the console for debugging purposes.

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

How can I get it to output a specially formatted string, like {Attribute} Large? I'm primarily concerned with Chrome support, but Node and other browsers would be nice, too.

Let's say I have this class.

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

And I create an instance and log it to the console for debugging purposes.

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

How can I get it to output a specially formatted string, like {Attribute} Large? I'm primarily concerned with Chrome support, but Node and other browsers would be nice, too.

Share Improve this question asked Apr 14, 2017 at 17:40 user457586user457586 4
  • 1 override Attribute.prototype.toString – Jonas Wilms Commented Apr 14, 2017 at 17:42
  • 3 @Jonasw Doesn't really work unless you do console.log(test.toString()). – Derek 朕會功夫 Commented Apr 14, 2017 at 17:43
  • 1 Probably use a custom logging function. For NodeJS, I would remend using util.format to format the process.stdout to create a custom logger. You can override console.log too, but it is not a good way to deal with stuff. – Ozil Commented Apr 14, 2017 at 17:50
  • Does this answer your question? Is it possible to override JavaScript's toString() function to provide meaningful output for debugging? – ggorlen Commented Feb 4, 2022 at 1:47
Add a ment  | 

3 Answers 3

Reset to default 8

A sane solution would probably be to use a custom logging function that stringifies Attribute values.

However, if you have a vendetta against people who need to maintain your code in the future, one solution that meets the technical requirements of this question is to have your class extend a type that console.log automatically serializes to string, like RegExp. When you console.log a RegExp instance, Chrome (and probably other environments) automatically serializes it to its bare /.../ expression. Simply overwrite what string it should serialize to by supplying a custom toString function, and you've got exactly what you asked for.

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

This is roughly equivalent to answering the question "How do I stop my house from flooding?" with "Put your house on a giant raft" instead of "Put some caulk in your basement" or "Move somewhere else." Some side effects will include:

  • Your objects will inherit regular expression properties like global and exec

  • Testing if your object is instanceof RegExp will of course return true, which might cause your object to be valid inputs for routines that only expect to operate on regular expression objects

Using further dark magic, you can solve the these issues by doing

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

immediately after your class definition, which will ensure that your this object will simply be run through the RexExp constructor (thereby flagging it for stringified log output) but not inherit from RexExp.prototype. By mixing class and prototype syntax together, you also ensure that your code is confusing and everyone is actively afraid of it.

apsiller's answer works great in Chrome and Firefox, but unfortunately, it doesn't work in Node. However, after some experimentation and research, I found a solution that does work in Node.

It turns out that Node's implementation of console.log has a built-in customization point, util.inspect.custom, so all you have to do is define a method with that symbol that returns whatever you want to print.

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;
  }
}

As console.log does not call to String you either do:

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

or you create your own logging function

发布评论

评论列表(0)

  1. 暂无评论