Why does implicit coercion for addition always produce a string?

霸气de小男生 提交于 2019-12-11 12:06:08

问题


If only the second operand in addition is a string then the output is a string:

let a = 1 + '2';
console.log(typeof a);  // string

And if, instead, only the first operand is a string, then the output is still a string:

let b = '1' + 2;
console.log(typeof b);  // string

I was guessing that there would be some kind of argument precedence. Is there a reason why this mathematical function defaults to a non-numerical output with mixed-type arguments?


回答1:


As it is often the case, the answer is "because the spec says so". More specifically, section 11.6.1 The Addition operator ( + ).

On step 7, you can read

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)

In other words, if at least one of the operands is a string, the result will be the concatenation of the string representation of both operands.

There is precedence in a way, because if both operands were functions the left one would be evaluated before the right one, but it doesn't matter for the algorithm that decides if the + operation should return a string or a number.

Note: I referred to the ECMAScript 5 spec but you can find something equivalent in the newer versions.




回答2:


When a single operator is part of an expression, the expression is performed left to right, but in JavaScript, if any one of the operands used with the + operator is a string, the other one will be converted to a string - it doesn't matter which one. This is because the + operation can mean string addition (concatenation) or mathematical addition. When one operand is a string, the JavaScript runtime correctly assumes that the + should mean string addition because the string could contain a non-numeric value and doing math with non-numeric values is problematic, to say the least.

You would need to do a conversion on the non-string before the concatenation occurs. This can be done in a number of ways:

console.log(1 + +"2");              // prepending a + to a string attempts to convert to a number

// Note that with all of the following there is a nested function call being performed
// and these functions take an argument, which requires () for the argument to be passed.
// Because of the nested (), that function call is performed first and the result of the 
// function call is returned to the expression.

console.log(1 + parseInt("2.4"));   // parse the integer portion of the string into a number
console.log(1 + parseFloat("2.4")); // parse the floating point number in the string into a number
console.log(1 + Number("2"));       // convert the string into a number

The basic operator precedence is:

  • Parenthesis
  • Exponents
  • Multiplication
  • Division
  • Addition
  • Subtraction

So, in the following examples, you can see that happening:

// Here, the order of operations will be:

  // Parenthesis:    (2/2) === 1
  // Multiplication: 10 * 1 === 10
  // Addition:       1 + 10 === 11
  // Subtraction:    11 - 3 === 8
console.log(1 + 10 * (2 / 2) - 3);

// But here, because of the string, the order of operations will be:

  // Parenthesis:    (2/2) === 1
  // Multiplication: 10 * 1 === 10
  // Addition:       "1" + 10 === "110" (one operand is a string, so the other converts to a string)
  // Subtraction:    "110" - 3 === 107  (the string "110" will be implicitly converted to a number
  //                                     becuase the - sign  only has one meaning in a mathmatical 
  //                                     expression)
console.log("1" + 10 * (2 / 2) - 3);

See JavaScript Operator Precedence for a full list of operators and their precedence.

See Unary + Operator for how it is used to convert to a number.

Also note that we're not talking about "arguments" here (an argument is what is passed to a method or function). These are operands in an expression with operators.



来源:https://stackoverflow.com/questions/50867329/why-does-implicit-coercion-for-addition-always-produce-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!