denysdovhan / wtfjs

🤪 A list of funny and tricky JavaScript examples
http://bit.ly/wtfjavascript
Do What The F*ck You Want To Public License
34.6k stars 2.54k forks source link

Explanation of first example is wrong #316

Open salmanarshad2000 opened 10 months ago

salmanarshad2000 commented 10 months ago

Explanation of this example is wrong: https://github.com/denysdovhan/wtfjs#-is-equal-

The abstract equality operator converts both sides to numbers to compare them

This is just wrong. Strings are compared as strings, null compared to undefined is true, to-primitive might return a string instead on number and so on.

Here is how this expression simplifies:

+[] == +![];

First step would be to convert ![] to false because of precedence.

tidalu commented 7 months ago

so, overall, your state is absolutely correct , but here is the thing, [] == ![] , for this problem, even though ![] is firstly converted to boolean, there what the author meant is both sides are converted to numbers to be primitive both sides, :: If the types of the two operands are different, JavaScript attempts to convert them to a common type :: but your state is also true

shyguy1412 commented 1 week ago

This is not entirely correct also. If you are following the specs precisely here is what happens

  1. We compare [] == false. I skip the step ![] because the right hand expression obviously first needs to be evaluated before the comparison starts
  2. The first relevent case is 9, the boolean is coerced to a number. We end up with [] == 0
  3. The next relevant case is 11, comparing an object to a non object. This coerces the object to a primitive by trying these methods in this order: Symbol.toPrimitive, valueOf, toString. A standard array doesnt have a toPrimitive symbol and valueOf just returns the array again. This means its coerced into a string using toString which concatenates all its elements with a comma. Since its empty, this will just be an empty string so we end up with '<empty string>' == 0
  4. After every step we start our cases from the top again so next case is 5, comparing a string to a number. This coerces the string to a number with Number(string) which in the case of an empty string leads us to 0 so now we finally end up with 0 == 0 which is true

So the correct example for this explanation really should be

[] == ![];
[] == false;
[] == 0;
'' == 0;
0 == 0;
true;

I think the coercion to a string is an important step that shouldn't be left out because otherwise the explanation gives off the impression that empty arrays are directly coerced into 0 all the time which is simply not true.