55

A comment by Vítor De Araújo on a blog post by Douglas Crockford points out that the two are not the same. He gives an example showing that a string is not like an object:

A string object and a string value are not the same thing:

js> p = "Foo"
Foo
js> p.weight = 42
42
js> p.weight // Returns undefined

js> q = new String("Foo")
Foo
js> q.weight = 42
42
js> q.weight
42

The string value cannot have new properties. The same thing is valid for other types.

What is going on here that an string is not an object? Am I confusing JavaScript with some other languages, where everything is an object?

4
  • 1
    …and I do not totally agree with Crockford: it's not necessary to use new Object (neither is new Array, use [] instead), but if you want to define a new instance of a (pre)defined class, you really should use the new operator, like in new Date() or new SchrodingersCat(). Commented Oct 11, 2010 at 16:00
  • @Marcel Korpel: "should use", or must use? Is there any other way to construct a new object from the Date object prototype? Commented Oct 20, 2010 at 15:26
  • 1
    Good question, in case of Date: must. If you call Date as a bare function, it returns the current date and time as a string. Also see Using constructor without operator 'new' and Does Javascript's new operator do anything but make life difficult? Commented Oct 20, 2010 at 15:40
  • See also Why are there two kinds of JavaScript strings? Commented Sep 17, 2015 at 16:34

2 Answers 2

105

"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
//...
Sign up to request clarification or add additional context in comments.

8 Comments

I prefer to not use uppercase with primitives, like boolean and number, to avoid confusion with the object wrappers Boolean and Number (but the ECMAScript specification does not do so). Also, NaN is a primitive value, too.
Marcel, yeah, object wrappers can cause confusion, e.g. if (new Boolean(false)) {alert(':D');}. Yes, NaN, positive and negative Infinity are values of the Number type.
Ah, yes, Infinity, I already thought I forgot some other value. How can one ever forget Infinity?
I want to stress that when using object methods to primitive values, the variable is only temporarily converted to an object and after the proposed operation, the object is converted back to a primitive. This concept can cause confusion, as you can see in String object versus literal - modifying the prototype?
Even after two years this answer remains effective! +1!!
|
5

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

2 Comments

this is the wrong comparison, these are clearly 2 different objects, so to compare the strings, you need to compare the values of new String("hello").valueOf()
@MichaelHabib It is the right comparison to demonstrate that comparing two objects compares the reference. Of course, you can convert the String object back to a string and compare it as a value. But the question is about how objects behave differently from strings. (Not about how to compare the values of objects).

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.