32
votes

The closest I got to something close to Python's repr is this:

function User(name, password){
         this.name = name;
         this.password = password;
}
User.prototype.toString = function(){
    return this.name;
};



var user = new User('example', 'password');

console.log(user.toString()) // but user.name would be even shorter

Is there a way to represent an object as a string by default? Or am I going to have to just use object.variable to get the results I want?

8
console.log(user+"") - epascarello
console.log(String(user)) - epascarello
@Epascarello Those both work, so if no one else answers and those are the only two ways of doing it I suggest you post those as an answer so you can get credit. I hope their is an alternative. - user3234209
Are you asking specifically about an equivalent to dict.__repr__? - Chris Martin
you can always write your own repr function that looks for __repr__ methods - Eevee

8 Answers

26
votes

JSON.stringify is probably the closest you are going to get from native libraries. It doesn't work well with objects, but you could define your own code to work around that. I searched for libraries that provide this functionality but didn't find anything.

14
votes

Node.js util.inspect

http://nodejs.org/api/util.html#util_util_inspect_object_options

To get the object representation that appears on the terminal as a string you can do:

const util = require('util');
console.log(util.inspect({ a: "0\n1", b: "c"}));
// Equivalent: automatically called by `console.log`.
console.log({ a: "0\n1", b: "c"});

output:

{ a: '0\n1', b: 'c' }
{ a: '0\n1', b: 'c' }

This is the same that would appear on the terminal if you copy pasted the string { a: "0\n1", b: "c"} into the terminal and pressed enter.

Override the inspect method of a class for a custom representation

This was asked at: How to change string representation of objects in Nodejs debug console view and mentioned at: https://stackoverflow.com/a/32866283/895245 and https://stackoverflow.com/a/54667225/895245 but here goes a fuller example:

const util = require('util');

class MyClass {
  constructor(a, b) {
    this.a = a;
    this.b = b;
  }
  [util.inspect.custom]() {
    return `a is ${this.a} and b is ${this.b}`;
  }
}

const my_object = new MyClass(1, 2);
console.log(util.inspect(my_object));
console.log(my_object);

Output:

a is 1 and b is 2
a is 1 and b is 2

The default inspect if we hadn't defined a custom [util.inspect.custom] would have been:

MyClass { a: 1, b: 2 }

That same representation also shows if you just directly inspect the object on a terminal:

> my_object
a is 1 and b is 2

In older Node.js, the syntax used to be just:

inspect(){}

but that was deprecated with message:

[DEP0079] DeprecationWarning: Custom inspection function on Objects via .inspect() is deprecated

as mentioned at:

Pretty print util.inspect with newlines and indentation

Not possible? Sigh:

One big advantage over JSON.stringify is that inspect takes care of circular dependencies for you. But without pretty print, it is a pain.

Tested in Node.js v10.15.1.

13
votes

In Nodejs, console.log representation of a Javascript object can be overridn by adding inspect() method to that Object

eg:

function User(name, password){
         this.name = name;
         this.password = password;
}
User.prototype.toString = function(){
    return this.name;
};
User.prototype.inspect = function(){ return 'Model: ' + this.name ; }

-Thanks to 'Ciro Santilli'

2
votes
String(user)

Is the best I can think of. I think another alternative may be to find a 3rd party lib that handles creating human readable presentation for objects.

2
votes

A quick shortcut for me is to wrap the value with an array literal, like this:

console.log([variable]);

The output in the browser's developer console makes it quite clear what the only element of the array is.

Screenshot of developer console on Firefox

1
votes

Node v6.6.0 introduced the util.inspect.custom symbol: it is a globally registered symbol accessible through Symbol.for('nodejs.util.inspect.custom'). It can be used to declare custom inspect functions.

Here's a usage example with OP's case:

function User(name, password){
  this.name = name;
  this.password = password;
  this[Symbol.for('nodejs.util.inspect.custom')] = () => this.name;
}

var user = new User('example', 'password');

console.log(user)  // 'example'
0
votes

As Andrew Johnson said, JSON.stringify is probably the closest you can get out of the box.

One common strategy for a repr is to output runnable Python code. If you want to do this, lave (opposite of eval) is a good choice.

Example:

var escodegen = require('escodegen')
var lave = require('lave')

function User(name, password){
             this.name = name;
             this.password = password;
}

var user = new User('example', 'password');

console.log(lave(user, {generate: escodegen.generate}));

Output (not as elegant as I had hoped!):

var a = Object.create({ 'constructor': function User(name, password){
             this.name = name;
             this.password = password;
} });
a.name = 'example';
a.password = 'password';
a;
0
votes

This is solution for NodeJS (not sure about browser). As https://nodejs.org/dist/latest-v8.x/docs/api/util.html#util_util_inspect_object_options says, you could add inspect(depth, opts) to your class and it will be called when you console.log(user_class_instance);

Therefore this should do the trick:

User.prototype.inspect = function(depth, opts){
    return this.name;
};