You Don't Know JS: Up & Going | Equality: can't understand something here

So , I came across the below while reading through You Don't Know JS: Up & Going (thanks @P1xt).

You should take special note of the == and === comparison rules if you’re comparing two non-primitive values, like objects (including function and array). Because those values are actually held by reference, both == and === comparisons will simply check whether the references match, not anything about the underlying values.

For example, arrays are by default coerced to strings by simply joining all the values with commas (,) in between. You might think that two arrays with the same contents would be == equal, but they’re not:

var a = [1,2,3];
var b = [1,2,3];
var c = "1,2,3";

a == c;     // true
b == c;     // true
a == b;     // false

I’m struggling to understand why a == b is false here? I think it’s because it’s comparing the actual ‘a’ and ‘b’ but not the contents of the array but how can a == c and b == c be true then?

1 Like

I really shouldn’t try to answer this type of question but I can’t help myself.

If I remember well, an array is an object, and so here a and b are 2 different objects.

So in a way I suppose the implicit coercion doesn’t work the way it does with b and c, because M Magic (the browser or whatever) sees two objects : it doesn’t have to coerce any side of the assignment.

Whereas with b and c, there is coercion.

Here’s probably a much better explanation.

2 Likes

While a and b might look like they’re identical, they are two different objects. Both of them are stored in different places in memory.

It goes like this:

  • Create an array that contains 1, 2 and 3, then store that somewhere in memory, then let the variable a contain that memory’s address.
  • Create another array that contains 1, 2 and 3, then store that somewhere in memory, then let the variable b contain that memory’s address.

So you have two arrays that are stored in different places in memory. When you compare them, what you’re actually comparing are their memory addresses, not their contents.

Comparing two objects is pretty straightforward. You’ll get true if and only if the variables you’re comparing point to the same object. If you instead did

var a = [1, 2, 3];
var b = a;

you’ll get true if you did a == b.

If what you’re comparing are not objects, the outcome depends on the types of the things you’re comparing, and whether you used == or ===.

If you used ===, you’ll always get false if what you’re comparing are different types (say, when you compare text with a number).

If you used ==, coercion comes into play, as in the case of a == c above: the array is coerced to a string, then compared to the other string, and it so happens that the array [1,2,3] looks like the string "1,2,3". This type of comparison follows certain rules, depending on the types of the data involved (these rules are explained in another YDKJS book).

6 Likes

thanks @timotheap ; i’m a step closer now! looks like there’s a few different steps to get a == b , which is ideally what i’d like to be true i guess…

This is explained quite well later, in types&values.

If you need a quick explanation, there it goes.
Take this code:
var a = 1;

Here, you declare variable ‘a’ and assign value 1 to it. You can think of ‘a’ as a box, into which you put value 1. Now, whenever you refer to ‘a’ in your code, you (metaphorically) take the box labeled ‘a’, open it, and you have value 1 inside.

But thats not how it works for objects in Javascript (arrays are objects).
var b = [1, 2, 3];

Here, you dont put the value inside the box. Javascript makes the value [1,2,3,] somewhere (doesnt matter where) and simply draws a line from ‘b’ to it. That’s what “held by a reference” means. Now, when you do this:
var b = [1,2,3];
var c = [1,2,3];
Javascript creates 2 separate arrays (both look the same - [1,2,3]), and points variable ‘b’ to one of them, and variable ‘c’ to the other. Now, when you compare those two variables, Javascript simply checks if they point to the same object (array). Thats why b == c prints false.

On the other hand, if you did:
var b = [1,2,3];
var c = b;
then you would get true, when comparing ‘b’ to ‘c’. Careful tho, because in this case, every change to ‘c’ will also affect ‘b’.

Hope it helps.

4 Likes

ah right , thanks @kevcomedia ; looks like i’m learning a whole lot today!

love the analogies @KamilCybulski , thanks for your help

So am I :yum: - the other two answers are so much clearer !

2 Likes

I haven’t gotten to this part in the series yet, but from reading what the original text says, I would not have understood this either. @kevcomedia - Your explanation is really clear and understandable. THANKS SO MUCH!!!