-1

I was looking at some legacy code, and I noticed the following code (simplified here):

const age = [ 33 ];
const year = 2021;
const yearOfBirth = year - age; // gives the number 1988

In other words, number - [number] is of type number

If, however I change it to

const age = [ 33, 44 ];

The subtraction doesn't work and I get NaN. This makes sense to me.

Why is the first operation valid? Where is such thing documented?


PS: I'm aware a similar thing holds for string[], since String.prototype.toString() is equivalent to String.prototype.join(""). But I don't know why this holds for numbers.

Nico
  • 790
  • 1
  • 8
  • 20

2 Answers2

1

To answer this question:

Why is the first operation valid? Where is such thing documented?

2021 - [33] is interpreted like this:

First, the array [33] is converted to a primitive, which means that toString is applied, which mean it's interpreted as "33"

Second, the string "33" is subtracted from the number 2021. To do that, it is first converted to a number, and then subtracted. This works OK because "33" can be converted to the number 33.

2021 - [33,44] is interpreted similarly:

First, the array [33,44] is converted to a primitive, applying toString, which produces "33,44". Second, this is converted to a number, producing NaN, and that means that the subtraction results in NaN.

It is documented at https://262.ecma-international.org/5.1/#sec-11.6.2, https://262.ecma-international.org/5.1/#sec-9.3, https://262.ecma-international.org/5.1/#sec-9.1 and https://262.ecma-international.org/5.1/#sec-8.12.8

But the code is clearly not ideal and should really be fixed.

Chris Lear
  • 6,592
  • 1
  • 18
  • 26
  • I already fixed it. I came up with the problem while replacing all the typescript `any` `any` `any` in the code by its real types. I should have figured out the `toString` casting and would have saved me from asking the question. Thank you – Nico Jun 17 '21 at 16:30
1

It is because [33].toString() becomes "33" and [33, 44].toString() becomes "33,44" which cannot be evaluated to either int or float.

Array.prototype.toString()

Taufik Nurrohman
  • 3,329
  • 24
  • 39