Autoconversion in [removed] Isn't it supposed

2019-07-21 07:06发布

问题:

(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?

回答1:

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:

  1. Let lref be the result of evaluating AdditiveExpression.
  2. Let lval be GetValue(lref).
  3. Let rref be the result of evaluating MultiplicativeExpression.
  4. Let rval be GetValue(rref).
  5. Let lprim be ToPrimitive(lval).
  6. Let rprim be ToPrimitive(rval).
  7. If Type(lprim) is String or Type(rprim) is String, then
    1. Return the String that is the result of concatenating ToString(lprim) followed by ToString(rprim)
  8. 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.



回答2:

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.