52

Why does the following statement return false in JavaScript?

new String('hello') === new String('hello')
Cody Gray - on strike
  • 239,200
  • 50
  • 490
  • 574
santosh kore
  • 976
  • 1
  • 12
  • 21
  • 4
    It's probably comparing the location of the strings, rather than the actual strings. If you save the strings to variables, then compare the variables, it should return true. – aashnisshah Sep 03 '14 at 15:02
  • 15
    For the same reason `[] === []` is `false`. – Felix Kling Sep 03 '14 at 15:03
  • 4
    For reference: http://stackoverflow.com/a/3586788/899126. Basically, it's because the comparison isn't being done between two strings, but two objects. You can call `.valueOf()` on the string objects, and your comparison will return true. – Chris Forrence Sep 03 '14 at 15:03
  • 2
    @aashnisshah that also returns false – Huangism Sep 03 '14 at 15:04
  • 1
    @aashnisshah: Variables don't have any impact on comparing values. They are just placeholders. – Felix Kling Sep 03 '14 at 15:05
  • `typeof (new String())` is "object" - you can't do strict comparisons on two objects, even if they are identical in terms of properties and values. See [MDN](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Comparison_Operators): *"Two distinct objects are never equal for either strictly or abstract comparisons."* – Ryan Wheale Sep 03 '14 at 20:33

7 Answers7

62

Two String objects will always be unequal to each other. Note that JavaScript has string primitive values as well as a String constructor to create wrapper objects. All object equality comparisons (especially with ===) are carried out as a test for reference equality. References to two different objects will of course never be equal to each other.

So "hello" === "hello" will be true because those are string primitives.

Kijewski
  • 25,517
  • 12
  • 101
  • 143
Pointy
  • 405,095
  • 59
  • 585
  • 614
  • 3
    If the operands are of the same type then `==` and `===` are identical, so `new String('hello') == new String('hello')` is also `false`. – Tim Down Sep 03 '14 at 15:04
  • thanks, but still i am not sure why if a = {} and b = {}, then a === b and a == b returns false – santosh kore Sep 03 '14 at 15:14
  • 16
    @santoshkore: Because you are comparing **two different** objects. A car manufacturer produces two cars of the same model. The cars are *similar*, but they are *not the same*. When you compare objects, you are testing for *identity*, not similarity. – Felix Kling Sep 03 '14 at 15:23
  • 1
    What if string interning were to be used? Would the two different objects be interned into one? Or is string interning only used on string _primitives_? – Cole Tobin Sep 03 '14 at 17:23
  • 1
    @ColeJohnson I don't think the JavaScript interpreter is allowed to coalesce two distinct objects; it would be weird behavior. Note that the string primitive inside a String instance can itself be interned. There's not much to a String instance, really, other than a reference to the primitive and the link to its prototype. – Pointy Sep 03 '14 at 17:26
19

You are comparing object instances, which is not like a string comparison ('hello' === 'hello') Comparing objects in Javascript is actually comparing the memory addresses of the objects and will always return false because memory addresses are different for each object.

Compare the string values instead of the object instance - jsFiddle

( String('hello') === String('hello') ) // returns true due to comparing strings

Strictly comparing two objects - false not the same object

new String('hello') === new String('hello')

Strictly comparing two strings - true, same returned value and same returned type

String('hello') === String('hello')
Brian Dillingham
  • 9,118
  • 3
  • 28
  • 47
  • 1
    What's the difference here? You should elaborate on that (since you are not directly answering the OP's question). – Felix Kling Sep 03 '14 at 15:07
  • `new String("hello") === new String("hello")` check type as well as reference that is why it returns `false` got it but `new String("hello") == new String("hello")` is comparing the objects instead of the value what this means? I was always thinking == compares only values. Please elaborate – santosh kore Sep 03 '14 at 15:21
  • Updated my answer to clarify a bit more – Brian Dillingham Sep 03 '14 at 15:30
  • 4
    @santoshkore: Objects *are* values. They are values of the Object data type. The difference is that `String()` returns a *primitive value* and `new String()` returns an *object value*. Primitive values are not unique like objects are, they don't have an ID. So when you compare them, there is nothing else to compare as their raw data. Each object is unique though, so if you compare objects you are comparing their identities. – Felix Kling Sep 03 '14 at 15:33
  • @FelixKling, you should combine all of your so awesomely informative comments into an answer that I can upvote. – Brian Dillingham Sep 03 '14 at 15:40
  • 3
    To others: notice the lack of a `new` keyword in the String comparison in this answer. – Casey Kuball Sep 03 '14 at 19:52
12

It evaluates to false because you're comparing two different objects: new will create a new object.

Related post: What is the 'new' keyword in JavaScript? Which explains in its (extensive) answer:

It [new] is 4 things:

  1. It creates a new object. The type of this object, is simply object.
  2. It sets this new object's internal, inaccessible, [[prototype]] property to be the constructor function's external, accessible, prototype object (every function object automatically has a prototype property).
  3. It executes the constructor function, using the newly created object whenever this is mentioned.
  4. It returns the newly created object, unless the constructor function returns a non-primitive value. In this case, that non-primitive value will be returned.
Community
  • 1
  • 1
BeyelerStudios
  • 4,243
  • 19
  • 38
  • 4
    While this link may answer the question, it is better to include the essential parts of the answer here and provide the link for reference. Link-only answers can become invalid if the linked page changes. – Alessandro Incarnati Sep 03 '14 at 17:14
  • 1
    while this is true, I suspect stackoverflow handling it's own links once they were to change their url-generation. the question was answered quickly by others so I didn't elaborate further. – BeyelerStudios Sep 03 '14 at 17:19
  • 1
    You still should not have answers that are just a link. – Cole Tobin Sep 03 '14 at 17:55
8

You are asking javascript to compare two different instances of the variable, not the string value that lives inside the variable.

So for example, lets say I have a piece of paper with the word "Hello World" written on it (Paper1) and my brother has a different piece of paper with the word "Hello World" written on it (Paper2).

When you say is Paper1 === Paper2 you will get false, beacuse no they are not the exact same piece of paper, even though the words written on the paper are the same.

If you where to say Paper1.toString() === Paper2 .toString() you would get true, beacuse we are comparing the words written on the paper, not the actual paper itself.

ccorrin
  • 502
  • 1
  • 5
  • 21
6
typeof(new String()) === 'object';
==> true

(new Object()) === (new Object());
==> false

Any "object" structure in the "Heap" is unique;

Heap vs. Stack

Community
  • 1
  • 1
Cody
  • 9,785
  • 4
  • 61
  • 46
6

Your code essentially says "Take a piece of paper and write 'hello' on it. Take another piece of paper and write 'hello' on that. Are they the same piece of paper?"

5

Also if you do if ( { hello: 1 } === { hello: 1 } ){ console.log( "yay" ); } the console.log never happen, because it's an object.

You can compare 2 literal objects (as my first example) by making a loop on these objects and when you find a difference you know the result. It's more difficult to do this trick in an instantiated object, compare 2 functions it's crazy.

But if JavaScript don't do it for you it's because this is very heavy, you have check each type of each attributes to stringify it if it's a function etc... and obviously it's not useful to do it.

You can use instanceof if you want to check 2 objects "origins", because typeof will return you "object". And for testing 2 "new String" object you have to use toString new String( "hello" ).toString() == new String( "hello" ).toString() or if you want to check the object without testing the attributes new String( "hello" ) instanceof String && new String( "hello" ) instanceof String

is true.

The link given by BeyelerStudios explain perfectly what the new do, hope it'll help.

Inateno
  • 115
  • 5