This statement:
var myString = new String('foo');
...creates a string object initialized with the characters f, o, and o.
This statement:
var myString = new String();
...creates a string object with no characters, but that doesn't matter because this statement:
myString = "foo";
...throws that string object away and replaces that variable's value with a new primitive string with those characters. The net result is exactly the same as:
var myString = "foo";
The reason the output from console.log is different is that the browser providing the console.log is trying to make it clear that one of them is an object and the other is a primitive.
Somewhat confusingly, JavaScript has both string objects and string primitives. (It also has number objects and number primitives.) There is almost never any reason to use new String, which creates a string object; just use the primitive (in your case, a literal) instead. Conversely, there are very good reasons not to use string objects, such as this:
console.log(new String("foo") === new String("foo")); // "false"
console.log(new String("foo") == new String("foo")); // "false"
console.log("foo" === "foo"); // "true"
Because string objects are objects, == and === compare object references, not the sequence of characters. While there may be some edge cases where that's what you want, 99.9% of the time, what you really want is to compare the values. The good news is that:
console.log("foo" == new String("foo")); // "true"
...but that won't be true if you use ===, which doesn't do any type coercion.
You might ask:
So if var myString = "foo" returns a primitive, not an object, how is it that myString.toUpperCase() and such work?
Good question: The answer is that the primitive is automatically promoted to an object so that we can make the function call. (In theory; in practice, implementations are smarter than that.)
new String()part in the second is redundant