Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multiplying an array with a single value by a number?

Tags:

javascript

Why does JavaScript allow you to multiply arrays with a single numeric value by another numeric value or by another array with a single numeric value?:

[3] * 3;
// 9

[3] * 2;
// 6

[3] * [3];
// 9

[1, 2] * 2
// NaN

I would expect NaN to be returned every time but as my experiments in Chrome have demonstrated this is not the case.

Is this the expected behavior? Does this behavior make sense? If so, why?

like image 218
Xaxis Avatar asked Jun 25 '13 15:06

Xaxis


3 Answers

[3] * 3;

The following steps are taken:

  • array is converted to a string [3] => "3"
  • the string is converted to a number Number("3") => 3
  • 3 * 3 gives 9

Similarly, for [1, 2] * 2:

  • array is converted to a string [1, 2] => ""1,2"
  • the string is converted to a number Number("1,2") => NaN
  • NaN * 3 gives NaN

For ECMA freaks among us ;) start here and follow the path multiplicative operator => ToNumber => ToPrimitive => [[DefaultValue]](number) => valueOf => toString

like image 196
georg Avatar answered Nov 07 '22 12:11

georg


What is happening here is that [3] is being coerced into a String type, which is just "3". Then in "3" * 3 the String value "3" gets converted into the number 3. You finally end up with 3 * 3, which evaluates to 9.

You can see this behavior if you do [3].toString() * 3 or "3" * 3, which also gives you 9,

So the following steps happen:

  • [3] * 3
  • [3].toString() * 3
  • "3" * 3
  • Number("3") * 3
  • 3 * 3
  • 9

In the case [1, 2], you eventually end up with "1, 2". But Number("1, 2") results in a NaN and a number multiplied with a NaN results in NaN.

like image 4
Vivin Paliath Avatar answered Nov 07 '22 12:11

Vivin Paliath


http://ecma-international.org/ecma-262/5.1/#sec-15.4.4.2

Since Array.prototype.valueOf is not available, it falls back to using the String version (as per http://ecma-international.org/ecma-262/5.1/#sec-9.9)

The toString renders an array with a single element as the value of the element (so [3].toString() is 3)

like image 1
SheetJS Avatar answered Nov 07 '22 12:11

SheetJS