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

javascript - What determines whether node prints `[object Object]` or a full object? - Stack Overflow

programmeradmin4浏览0评论

Minor note: I'm very familiar with console.log(), JSON.stringify(), Object.prototype.toString(), util.inspect() etc - this question isn't asking how to show the contents of objects, but rather why node's behavior changes in different circumstances.

I know I can console.log(someObject) and node will print:

[object Object]

node js function return [object Object] instead of a string value has some good information on this.

I know that [object Object] is from Object.prototype.toString()

I know I can console.log(JSON.stringify(someObject, null, 2) and node will print:

{
  foo: 'bar'
}

Or use util.inspect() etc. See this answer

However it seems that sometimes node will actually print the objects contents

If I make a new file called runme.js with the contents:

console.log({foo: 'bar'})

And run node runme.js node will print

{ foo: 'bar' }

Not [object Object]

Why is node not printing [object Object]?

Edit: per Keith's question, [object Object] will appear when I run:

console.log(`Check me out ${{foo: 'bar'}}`)

Logs [object Object]

What determines whether node uses Object.prototype.toString() (aka [object Object]) vs printing the contents of the object?

Minor note: I'm very familiar with console.log(), JSON.stringify(), Object.prototype.toString(), util.inspect() etc - this question isn't asking how to show the contents of objects, but rather why node's behavior changes in different circumstances.

I know I can console.log(someObject) and node will print:

[object Object]

node js function return [object Object] instead of a string value has some good information on this.

I know that [object Object] is from Object.prototype.toString()

I know I can console.log(JSON.stringify(someObject, null, 2) and node will print:

{
  foo: 'bar'
}

Or use util.inspect() etc. See this answer

However it seems that sometimes node will actually print the objects contents

If I make a new file called runme.js with the contents:

console.log({foo: 'bar'})

And run node runme.js node will print

{ foo: 'bar' }

Not [object Object]

Why is node not printing [object Object]?

Edit: per Keith's question, [object Object] will appear when I run:

console.log(`Check me out ${{foo: 'bar'}}`)

Logs [object Object]

What determines whether node uses Object.prototype.toString() (aka [object Object]) vs printing the contents of the object?

Share Improve this question edited Oct 27, 2020 at 12:48 mikemaccana asked Oct 27, 2020 at 10:27 mikemaccanamikemaccana 124k110 gold badges432 silver badges534 bronze badges 5
  • 1 Have you an example of someObject that does this, as that might help. eg. {foo: 'bar'} would work fine anyway without using stringify.. – Keith Commented Oct 27, 2020 at 10:49
  • 1 Does the object implement the nodejs.util.inspect.custom symbol method? – VLAZ Commented Oct 27, 2020 at 10:57
  • @Keith added an example. Per the answers, looks like the ES6 string literal was running the toString() before the console.log could do anything, – mikemaccana Commented Oct 27, 2020 at 11:12
  • @VLAZ no it doesn't. Good question though! – mikemaccana Commented Oct 27, 2020 at 11:14
  • Yes, that makes sense why it's [object Object], in theory though you could create your own template literal parser to show it differently.. – Keith Commented Oct 27, 2020 at 11:17
Add a ment  | 

3 Answers 3

Reset to default 5

Console logging will output [object Object] for an object value that was converted to a string before being passed as a parameter to a console method, or if an object value argument is consumed and inserted into a format string passed as the first argument.

The latter occurs if a format string contains C-like percentage prefixed conversion sequences within it that consume the next unused argument and embed it the format string.

If a format string is used, and more (object) arguments are passed to the method than are used by the format string, remaining unconsumed arguments that are objects are logged as object values without conversion to strings.

So some expected values and actual log output:

const someObject = {a: "a"};

// expected output: "string [object Object]"
console.log( "string " + someObject);

// expected output: "same deal: [object Object]"
console.log( "same deal: %s", someObject); // converted by format string

// expected output: 'someObject = {a: "a"}'
console.log( "someObject = ", someObject) // someObject was not consumed by format string!

Of course Node does not present an interactive object view on the text console, and in simple cases it can look a lot like JSON.stringify() output. However Node does make an attempt to

  • identify the constructor of the object,
  • color code values according to their data type
  • handle presentation of circular references

that expand its debugging potential beyond simple JSON.stringify() conversions.

In my experience, console.log detects when it is passed the object and prints the entire object like the example you showed.

console.log({foo: 'bar'})
// => { foo: 'bar' } 

However when an object is concatenated to a string, it's converted to a string using the .toString() method and then passed to the console.log method.

Example:

console.log('' + { foo: 'bar' }) 
// => [object Object]

This is because before passing to console.log method, the expression is evaluated to '' + { foo: 'bar' }.toString(). That's my understanding of how it works. Though the internal workings might be more plex.

As has been worked out, template literals will box the args using .toString.

But if you find you use template literals a lot for debugging, and you want to use JSON.stringify instead.

Here is a simple example below.

function tagJSON(strings, ...args) {
  const output = [];
  let nextString = 0;
  let nextArg = 0;
  //loop all string & args
  while (nextArg < args.length) {
    output.push( strings[nextString] );
    output.push( JSON.stringify(args[nextArg]) );
    nextArg += 1;
    nextString += 1;
  } 
  //might be a string left at the end..
  if (nextString < strings.length)
    output.push( strings[nextString] ); 
  //finally output our new concated string & stringified(args)
  return output.join('');
}

var someobject = {x: 'y'};
let output = tagJSON`someobject = ${someobject}`;

console.log(output);
console.log(tagJSON`boolean = ${true} or ${false}`);
console.log(tagJSON`strings will double quote ${'hello world'}`);

发布评论

评论列表(0)

  1. 暂无评论