This stems from a JavaScript quirk: there are primitive strings and object strings. A primitive string is, well, your everyday string:
typeof "Hi! I'm a string!" // => "string"
However, any time you use new
, you create an object rather than a primitive:
typeof new String("Hi! I'm a string!") // => "object"
JavaScript also implicitly creates an object string out of a primitive string whenever you access a property, since only objects can have properties:
var s = "Hi! I'm a string!";
s.property = 6; // s implicitly coerced to object string, property added
console.log(s.property); // => undefined
// property was added to the object string, but then the object string was
// discarded as s still contained the primitive string. then s was coerced again
// and the property was missing as it was only added to an object whose reference
// was immediately dropped.
You almost never want an object string because of its quirks (e.g., an empty object string is truthy), so rather than using new String
, you almost always want String
instead. String
without new
can even convert an object string back into a primitive string:
typeof String(new String("Hi! I'm a string!")) // => "string"
I don't know if this issue surfaces in TypeScript, but the primitive/object distinction and especially the truthiness issue becomes very odd with Boolean
. For example:
var condition = new Boolean(false);
if(condition) { // always true; objects are always truthy
alert("The world is ending!");
}
In short, it's because of the object/primitive distinction. You almost always want primitives where you have the option.