0

I have read that when we compare object with a number type-coercion happens. ToPrimitive on object gets called which then calls valueOf and if required toString. But I not able to get my head around how its actually working in the code given below

[ null ] == 0             // true
[ undefined ] == 0        // true
[ ] == 0                  // true
[ "-0" ] == 0             // true

[ false ] == 0            // false
[ true ] == 0             // false

How is [ false ] == 0 is false but [ null ] , [ undefined ] is true

Akash Singh
  • 547
  • 5
  • 8
  • 1
    When coercing an Array, JavaScript can only do one thing: `toString`. Which is an alias of `join` by default. Array.join normally calls `toString` on each item, but it has a special behavior for *null* and *undefined* which are not boxable: just output an empty string. So you get an empty string, which, coerced to number, becomes zero. Whereas booleans have a `toString` method which outputs "true" or "false". – Touffy Sep 17 '20 at 12:59

1 Answers1

1

Because calling Number([false]), which results in Number('false'), returns NaN, whereas '' (empty or only white-space), null and undefined initialize a Number as 0. The Number wrapper returns a primitive value.

Except for null and undefined, all primitive values have object equivalents that wrap around the primitive values.

As Touffy noted in the comments, before calling the wrapper, the array needs to be resolved by calling toString on the value. Once the string value is determined, the wrapper handles the parsing.

Number([0])         // [0].toString()         => Number("0")     => 0
Number([undefined]) // [undefined].toString() => Number("")      => 0
Number([null])      // [null].toString()      => Number("")      => 0 
Number([false])     // [false].toString()     => Number("false") => NaN

Both null and undefined are valid arguments for producing a Number primitive, because they are the absence of a value. Blank or empty strings are also considered empty values. Since the string value of 'false' and false (boolean) values are non-empty and not numeric, you will get NaN.

Note: This is slightly different from how integer parsing works.

parseInt('0')     // 0
parseInt('')      // NaN
parseInt('false') // NaN

You can check out string_number_conversions_internal.h over at the Chromium Code Search to see how parsing works for strings.

Mr. Polywhirl
  • 42,981
  • 12
  • 84
  • 132
  • 1
    That would be a bit less incorrect if you removed the `new`. `Number(x)` returns a primitive *number*, whereas `new Number(x)` returns an *instance of Number*. – Touffy Sep 17 '20 at 12:48
  • @Touffy I believe I worded it better. – Mr. Polywhirl Sep 17 '20 at 12:56
  • 1
    yeah, well… except for the missing step where the array is coerced to a string before being coerced back to a number. – Touffy Sep 17 '20 at 13:00