This one just stabbed me hard. I don't know if it's the case with all browsers (I don't have any other competent browser to test with), but at least Firefox has two kind of string objects.
Open up the Firebugs console and try the following:
>>> "a"
"a"
>>> new String("a")
String { 0="a"}
As you can visually observe, Firefox treats new String("a")
and "a"
differently. Otherwise however, both kinds of strings seem to behave the same. There is, for instance, evidence that both use the same prototype object:
>>> String.prototype.log = function() { console.log("Logged string: " + this); }
function()
>>> "hello world".log()
Logged string: hello world
>>> new String("hello world").log()
Logged string: hello world
So apparently, both are the same. That is, until you ask for the type.
>>> typeof("a")
"string"
>>> typeof(new String("a"))
"object"
We can also notice that when this
is a string, it's always the object form:
>>> var identity = function() { return this }
>>> identity.call("a")
String { 0="a"}
>>> identity.call(new String("a"))
String { 0="a"}
Going a bit further, we can see that the non-object string representation doesn't support any additional properties, but the object string does:
>>> var a = "a"
>>> var b = new String("b")
>>> a.bar = 4
4
>>> b.bar = 4
4
>>> a.bar
undefined
>>> b.bar
4
Also, fun fact! You can turn a string object into a non-object string by using the toString()
function:
>>> new String("foo").toString()
"foo"
Never thought it could be useful to call String.toString()
! Anyways.
So all these experiments beg the question: why are there two kinds of strings in JavaScript?
Comments show this is also the case for every primitive JavaScript type (numbers and bools included).