How is a Javascript string not an object?
"Everything is an object"... that's one of the big misconceptions that exist all around the language.
Not everything is an object, there are what we call primitive values, which are string, number, boolean, null, and undefined.
That's true, a string is a primitive value, but you can access all the methods inherited from String.prototype
as if it were an object.
The property accessor operators (the dot and the bracket notation), temporarily convert the string value to a String object, for being able to access those methods, e.g.:
"ab".charAt(1); // "b"
What happens behind the scenes is something like this:
new String("ab").charAt(1); // "b", temporal conversion ToObject
As with the other primitive values, such as Boolean
, and Number
, there are object wrappers, which are simply objects that contain the primitive value, as in your example:
var strObj = new String("");
strObj.prop = "foo";
typeof strObj; // "object"
typeof strObj.prop; // "string"
While with a primitive:
var strValue = "";
strValue.prop = "foo";
typeof strValue; // "string"
typeof strValue.prop; // "undefined"
And this happens because again, the property accessor on the second line above, creates a new temporal object, as:
var strValue = "";
new String(strValue).prop = "foo"; // a new object which is discarded
//...
The most important difference between a string and an object is that objects must follow this rule for the ==
operator:
An expression comparing Objects is only true if the operands reference the same Object.
So, whereas strings have a convenient ==
that compares the value, you're out of luck when it comes to making any other immutable object type behave like a value type.
(There may be other differences too, but this is the only one that causes JavaScript developers excitement on a daily basis). Examples:
"hello" == "hello"
-> true
new String("hello") == new String("hello") // beware!
-> false