3

I'm working on a lecture about hard to understand JavaScript code and of course on of the weak point of JavaScript is knowing what == / === will return. I found this great answer in stack that covers this subject nicely - Which equals operator (== vs ===) should be used in JavaScript comparisons?

one of the things that caught my eyes (probably because I wasn't aware of it until now) was that you can use String Objects instead of primitives and you will get different result in your conditions -

"abc" == new String("abc")    // true
"abc" === new String("abc")   // false

I wanted to test it and found out a few not so intuitive results using String Objects -

new String("abc") === new String("abc")    // false

and even

new String("abc") == new String("abc")   // false

at the beginning I thought this is a browser bug, but I tested it both on chrome and Firefox. So I'd be really happy if some one could share more information how can it be that comparing a literal string and a string object will be truthy but comparing two "equal" string objects will be falsy

Community
  • 1
  • 1
Yoni Jah
  • 773
  • 7
  • 15
  • 1
    Try this: `console.log(typeof (new String("abc"))); console.log(typeof "abc");` – Ian Apr 22 '13 at 14:33

1 Answers1

5

comparing two "equal" string objects will be falsy

I've highlighted the important word above. Two object references are never equal to each other unless they refer to exactly the same object.

You're creating two new instances of String. That's two separate objects, even if they do have the same string value.

var s1 = new String("abc"),
    s2 = new String("abc");

s1 === s1; // true
s1 === s2; // false

This is summarised in the spec by the following line in both the abstract equality algorithm and the strict equality algorithm:

Return true if x and y refer to the same object. Otherwise, return false.

James Allardice
  • 164,175
  • 21
  • 332
  • 312
  • im not an expert but shouldn't this: `new String("abc") == new String("abc")` be truthy? – x4rf41 Apr 22 '13 at 14:34
  • 1
    @x4rf41 - No, for the same reason `{ x: 1 } == { x: 1 }` is not true. – James Allardice Apr 22 '13 at 14:34
  • @x4rf41 I'm betting `"abc" == new String("abc")` is truthy is because since one of the operands is a string, it coerces the other, and in that comparison, they are `==` (which is what I think would lead you to think `new String("abc") == new String("abc")` is truthy, but isn't, since they're both objects) – Ian Apr 22 '13 at 14:36
  • 1
    @Ian - Exactly. The `==` (abstract equality operator) will cause the coercion of its arguments. – James Allardice Apr 22 '13 at 14:37
  • @JamesAllardice Right, but I was hopefully trying to explain why they might **think** `new String("abc") == new String("abc")` is truthy. They're already the same type, so there's no coercion. In the OP, `"abc" == new String("abc")` is truthy because the object is coerced into the string. I'm just thinking that's why they were confused about this specific case – Ian Apr 22 '13 at 14:40
  • 1
    JamesAllardice and @Ian good explanation. I completely missed that since both are Objects they will be compared as Objects – Yoni Jah Apr 22 '13 at 14:46