53

As per this documentation,

The string representations of each of these objects are appended together in the order listed and output.

Also as per answer

The + x coerces the object x into a string, which is just [object Object]:

So, my question is

If I do

str = new String("hello")
console.log(str) //prints the string object but not 'hello'
console.log(""+str) //prints "hello"

So, in first case, it simply prints the object (doesn't invoke the toString() method).

But in second case, it doesn't coerce but simply print the primitive value. Why is that so?

Which method does console.log invokes to print the object?

Please note that - this is not a duplicate of this question.

Community
  • 1
  • 1
gurvinder372
  • 66,980
  • 10
  • 72
  • 94

4 Answers4

28

Console API is not a standard API that is defined in any specification but is something that is implemented across all browsers, so vendors are usually at their liberty to implement in their own fashion as there's no standard spec to define the output of any methods in API.

Unless you check the actual implementation of the Console API for a particular browser, you can never be sure. There's a tracker on GitHub listing the differences between implementation from major browsers.

If you look at the implementation in FF (available here - search for log), it has a comment below

A multi line stringification of an object, designed for use by humans

The actual implementation checks for the type of argument that is passed to log() and based on it's type, it generates a different representation.

Coming to your case, log() prints two different values for strings created using literal notation and strings created using String constructor because they are two different types. As explained here, Strings created using literal notation are called String Primitives and strings created using String constructor are called String Objects.

var str1 = 'test';
var str2 = new String('hello');

typeof str1 // prints "string"
typeof str2 // prints "object"

As the types differ, their string representation differs in the Console API. If you go through the code for FF's Console implementation, the last statement is

return "  " + aThing.toString() + "\n";

So to answer your question, Console API in FF calls toString() on the argument only if the argument type is not one of {undefined,null,object,set,map} types. It doesn't always call toString() or valueOf() methods. I didn't check the implementation of Chrome, so I won't comment on that.

Arkantos
  • 6,530
  • 2
  • 16
  • 36
  • 1
    It's now [a standard](https://github.com/whatwg/console) you might want to update your answer to reflect that. – Benjamin Gruenbaum Aug 14 '18 at 15:04
  • That str2 prints type object is one of the reasons Google's style guide says to ["never use new on the primitive object wrappers"](https://google.github.io/styleguide/jsguide.html#disallowed-features-wrapper-objects) – Josh Desmond Mar 23 '21 at 18:42
4

This is more typing but will invoke obj.toString() as well:

console.log(`${obj}`);
baz
  • 1,317
  • 15
  • 10
3

It does not utilize toString, you can do something like this

clog = function(msg){console.log(msg.toString());}
clog(myObj);
A.Zaben
  • 675
  • 6
  • 10
1

console.log(str) calls str.valueOf() I guess. From JavaScript- The Definitive Guide Its job is to convert an object to a primitive value. The valueOf() method is invoked automatically when an object is used in a numeric context, with arithmetic operators (other than +) and with the relational operators, for example. Most objects do not have a reasonable primitive representation and do not define this method.

---edit----Sorry,copy the wrong line, I mean the ""+str,since there's a type converting

cyl19910101
  • 176
  • 1
  • 7