Search code examples
javascripttypescriptbabeljsv8

Unexpected multiplication behavior


Can anyone explain what makes this valid? String in an array multiplied yields the result like the array or string never mattered.

equation

["155"] * 100 = 15500


Solution

  • When a non-numeric value is operated on with something that only makes sense for numeric values - like * or / or % - JS attempts to coerce the non-numeric value into a numeric value. Number(['155']) turns into 155. It's weird, but legal. Usually, if you see code which relies on something like that, it's bad code that deserves refactoring.

    This behavior is described in the specification here, ApplyStringOrNumericBinaryOperator:

    1. Let lnum be ? ToNumeric(lval).
    2. Let rnum be ? ToNumeric(rval).

    (...do calculations on lnum and rnum)

    If the value can't be converted to a sensible number - for example, 'a' - then you'll get NaN as a result, but it doesn't throw an error.

    ["155"] turns into the number 155 because, when ["155"] is converted to a primitive, it gets joined by ,s: ["155"].join(',') results in the string '155'. This primitive then gets converted into the number 155.

    Arrays with more than 1 item can't be converted to numbers, because a comma is not a valid numeric character:

    const arr = [1, 2];
    console.log(
      String(arr),
      Number(arr)
    );