(Firefox32, Win 7)
When using the scratchpad:
var a = "2";
a = 1 - 1 + a;
console.log(a, typeof a);
a = 1 + a - 1;
console.log(a, typeof a);
(Firefox32, Win 7)
When using the scratchpad:
var a = "2";
a = 1 - 1 + a;
console.log(a, typeof a);
a = 1 + a - 1;
console.log(a, typeof a);
leads in the console to:
"02" "string"
101 "number"
Am I doing something wrong?
I'm sure I have converted strings to numbers that way very often, and it worked. (Though I like to use the explicit converting functions much more, but as it worked so flawlessly for so long, ... :/ )
And why is the third line a number? But not the second? And why is it 101?
Share Improve this question edited May 17, 2021 at 5:59 adiga 35.3k9 gold badges65 silver badges87 bronze badges asked May 8, 2015 at 15:59 JohnJohn 60610 silver badges29 bronze badges 2- no. 1 + "2" === "12" && "1" + 2 === "12" – Farzher Commented May 8, 2015 at 16:01
- 1 3rd is number because minus is the first thing that happens. "2" - 1 === 1 (minus does convert to Number because it's not used with strings) – Farzher Commented May 8, 2015 at 16:05
2 Answers
Reset to default 4Isn't it supposed to convert a string to a number when done like stringvar = 1+stringvar?
Nope. :-) If either operand is a string, it's string concatenation, not addition. This is defined by §11.6.1 of the spec in Step 7:
- Let lref be the result of evaluating AdditiveExpression.
- Let lval be GetValue(lref).
- Let rref be the result of evaluating MultiplicativeExpression.
- Let rval be GetValue(rref).
- Let lprim be ToPrimitive(lval).
- Let rprim be ToPrimitive(rval).
- If Type(lprim) is String or Type(rprim) is String, then
- Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
- Return the result of applying the addition operation to ToNumber(lprim) and ToNumber(rprim). See the Note below 11.6.3.
(My emphasis on "or")
Re your third example, 1 + a - 1
where a
is "02"
:
1 + "02" - 1
The addition (binary +
) and subtraction (binary -
) operators have the same precedence and both are left-to-right associative, so that's performed like this:
(1 + "02") - 1 => "102" - 1 => 101
The +
is string concatenation, but since the subtraction operator -
always works with numbers, it coerces the "102"
to 102
before subtracting 1
from it to get 101
.
This is how string concatenation works.
// Number + String -> concatenation 5 + "foo" // "5foo"
– MDN's Addition Operator usage examples
You can get around this by using the Unary Plus operator (+
) to avoid having to call parseInt
:
a = 1 + +a;
Unary plus (
+
)The unary plus operator precedes its operand and evaluates to its operand but attempts to converts it into a number, if it isn't already. Although unary negation (-) also can convert non-numbers, unary plus is the fastest and preferred way of converting something into a number, because it does not perform any other operations on the number.