While working on an isNumeric
function I found this edge case:
[5]
is considered a number, can be used with numerical operators like +
, -
,/
etc and gives 5
when given to parseFloat
.
Why does JavaScript convert a single value array to a number?
For example
const x = [10];
console.log(x - 5, typeof x);
While working on an isNumeric
function I found this edge case:
[5]
is considered a number, can be used with numerical operators like +
, -
,/
etc and gives 5
when given to parseFloat
.
Why does JavaScript convert a single value array to a number?
For example
const x = [10];
console.log(x - 5, typeof x);
gives
5 object
Share
Improve this question
edited Jun 14, 2019 at 14:05
CertainPerformance
371k55 gold badges349 silver badges356 bronze badges
asked Jun 14, 2019 at 11:37
ManavMManavM
3,0982 gold badges21 silver badges33 bronze badges
2
-
3
A tiny thing to note: "can be used with numerical operators like
+
" - This is correct, but the result of[10]+5
wouldn't be15
, it would be"105"
. As CertainPerformance explains below, the array is converted to a ma-separated string before the operation is performed, and where the-
operator will coerce the surrounding expressions to numbers, the+
operator does not. (e.g.,"10" + 5 === "105"
) – Tyler Roper Commented Jun 14, 2019 at 14:16 -
7
@TylerRoper: I find it curious (and IMHO unfortunate) that
"use strict"
didn't clean up more of that kind of nonsense. Some JavaScript implementations manage to eke amazing levels of performance out of the language, but many aspects of the language are mind-bogglingly horrible. – supercat Commented Jun 14, 2019 at 20:39
1 Answer
Reset to default 24The -
operator attempts to coerce its surrounding expressions to numbers. [5]
, when converted to a primitive (joining all elements by ,
), evaluates to '5'
, which can be clearly converted to a number without issue.
See the spec:
AdditiveExpression : AdditiveExpression - MultiplicativeExpression
- Let lref be the result of evaluating AdditiveExpression.
- Let lval be GetValue(lref).
- ReturnIfAbrupt(lval).
- Let rref be the result of evaluating MultiplicativeExpression.
- Let rval be GetValue(rref).
- ReturnIfAbrupt(rval).
- Let lnum be ToNumber(lval).
- ReturnIfAbrupt(lnum).
- Let rnum be ToNumber(rval).
- ReturnIfAbrupt(rnum).
- Return the result of applying the subtraction operation to lnum and rnum. See the note below 12.7.5.
Where ToNumber
does, in the case of an object:
- Let primValue be ToPrimitive(argument, hint Number).
- Return ToNumber(primValue).
which leads to ToPrimitive, calling toString
on the array, which leads to Array.prototype.toString, which calls .join
.