Search code examples
javascriptobjectequality

Why does ("foo" === new String("foo")) evaluate to false in JavaScript?


I was going to start using === (triple equals, strict comparison) all the time when comparing string values, but now I find that

"foo" === new String("foo")

is false, and same with this:

var f = "foo", g = new String("foo");
f === g; // false

Of course:

f == g; // true

So is it recommended to always use == for string comparison, or always convert variables to strings before comparing?


Solution

  • "foo" is a string primitive. (this concept does not exist in C# or Java)

    new String("foo") is boxed string object.

    The === operator behaves differently on primitives and objects.
    When comparing primitives (of the same type), === will return true if they both have the same value.

    When comparing objects, === will return true only if they refer to the same object (comparing by reference). Thus, new String("a") !== new String("a").

    In your case, === returns false because the operands are of different types (one is a primitive and the other is an object).


    Primitives are not objects at all.
    The typeof operator will not return "object" for primitives.

    When you try to access a property of a primitive (using it as an object), the Javascript language will box it to an object, creating a new object every time. This is described in the specification.

    This is why you cannot put properties on primitives:

    var x = "a";
    x.property = 2;
    alert(x.property) //undefined
    

    Each time you write x.property, a different boxed String object is created.