为什么加法的隐式强制总是产生一个字符串?

时间:2018-06-14 23:38:56

标签: javascript operator-precedence coercion

如果只有第二个操作数是一个字符串,那么输出是一个字符串:

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

相反,如果只有第一个操作数是一个字符串,那么输出仍然是一个字符串:

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

我猜测会有某种参数优先权。是否有理由将此数学函数默认为具有混合类型参数的非数字输出?

2 个答案:

答案 0 :(得分:2)

通常情况下,答案是“因为规范是这样说的”。更具体地说,section 11.6.1 The Addition operator ( + )

在第7步,您可以阅读

  

如果Type( lprim )是String或Type( rprim )是String,那么
  返回串联ToString( lprim )后跟ToString( rprim

的结果的字符串

换句话说,如果至少有一个操作数是字符串,则结果将是两个操作数的字符串表示的串联。

在某种程度上有优先权,因为如果两个操作数都是函数,那么左边的操作数将在右边的操作数之前进行评估,但是算法决定+操作是否应该返回一个字符串并不重要或者数字。

注意:我参考了ECMAScript 5规范,但你可以在新版本中找到相同的东西。

答案 1 :(得分:1)

当单个运算符是表达式的一部分时,表达式从左向右执行,但在JavaScript中,如果与+运算符一起使用的任何一个操作数是字符串,则另一个将被转换到一个字符串 - 它不重要。这是因为+操作可能意味着字符串添加(连接)或数学添加。当一个操作数是一个字符串时,JavaScript运行时正确地假定+应该意味着字符串添加,因为字符串可能包含非数字值,并且使用非数字值进行数学运算是有问题的,至少可以说。 / p>

在连接发生之前,您需要对非字符串进行转换。这可以通过多种方式完成:



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




基本运算符优先级为:

  • 括号
  • 指数
  • 乘法
  • 加成
  • 减法

因此,在以下示例中,您可以看到发生这种情况:



// 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);




有关运营商及其优先顺序的完整列表,请参阅 JavaScript Operator Precedence

请参阅 Unary + Operator 了解如何使用它转换为数字。

另请注意,我们并未谈及"论证"这里(参数是传递给方法或函数的东西)。这些 操作数