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

JavascriptObjectEquality

Javascript Problem Overview


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?

Javascript Solutions


Solution 1 - Javascript

"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.

Solution 2 - Javascript

Using ===,

  • an Object is never equal to anything except another reference to itself.

  • a primitive is equal when compared to another primitive if their type and value are the same.

Solution 3 - Javascript

The new word is a criminal here (as usual, may I say)...

When you use new, you explicitly express your desire to work with object. It might be surprising for you, but this:

var x = new String('foo');
var y = new String('foo');
x === y; 

... will give you a mighty false. It's simple: compared are not the objects' insides, but the objects' references. And they, of course, are not equal, as two different objects were created.

What you probably want to use is conversion:

var x = String('foo');
var y = String('foo');
x === y;

... and that will give you, as expected, true as result, so you can rejoice and prosper with your equal foos forever. )

Solution 4 - Javascript

foo is the pure string and new String("foo") is the Object String

Solution 5 - Javascript

From the node.js REPL ("node" on the command-line if installed):

> "foo" === (new String("foo")).valueOf()
true
> "foo" === new String("foo")
false
> typeof("foo")
'string'
> typeof(new String("foo"))
'object'
> typeof((new String("foo")).valueOf())
'string'

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMichael ButlerView Question on Stackoverflow
Solution 1 - JavascriptSLaksView Answer on Stackoverflow
Solution 2 - Javascriptuser1106925View Answer on Stackoverflow
Solution 3 - Javascriptraina77owView Answer on Stackoverflow
Solution 4 - JavascriptDanilo ValenteView Answer on Stackoverflow
Solution 5 - JavascriptmdaView Answer on Stackoverflow