(Firefox32, Win 7)
When using the scratchpad:
var a = "2";
console.log('a',a);
a = 1-1 + a;
console.log('a',a);
a = 1 + a -1;
console.log('a',a);
leads in the console to:
"a" "2"
"a" "02"
"a" 101
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?
Isn'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.