加性操作符

​ 加性操作符,即加法和减法操作符,一般都是编程语言中最简单的操作符。不过,在 ECMAScript 中,这两个操作符拥有一些特殊的行为。与乘性操作符类似,加性操作符在后台会发生不同数据类型的 转换。只不过对这两个操作符来说,转换规则不是那么直观

  1. 加法操作符

    加法操作符(+)用于求两个数的和,比如: let result = 1 + 2;

    如果两个操作数都是数值,加法操作符执行加法运算并根据如下规则返回结果:

    • 如果有任一操作数是 NaN,则返回 NaN;
    • 如果是 Infinity 加 Infinity,则返回 Infinity;
    • 如果是-Infinity 加-Infinity,则返回-Infinity;
    • 如果是 Infinity 加-Infinity,则返回 NaN;
    • 如果是+0 加+0,则返回+0;
    • 如果是-0 加+0,则返回+0;
    • 如果是-0 加-0,则返回-0。

    不过,如果有一个操作数是字符串,则要应用如下规则:

    • 如果两个操作数都是字符串,则将第二个字符串拼接到第一个字符串后面;

    • 如果只有一个操作数是字符串,则将另一个操作数转换为字符串,再将两个字符串拼接在一起。

    如果有任一操作数是对象、数值或布尔值,则调用它们的 toString()方法以获取字符串,然后再

应用前面的关于字符串的规则。对于 undefined 和 null,则调用 String()函数,分别获取 “undefined”和”null”。

​ 看下面的例子:

let result1 = 5 + 5; // 两个数值
console.log(result1); // 10
let result2 = 5 + "5"; // 一个数值和一个字符串
console.log(result2); // "55"

​ 以上代码展示了加法操作符的两种运算模式。正常情况下,5 + 5 等于 10(数值),如前两行代码 所示。但是,如果将一个操作数改为字符串,比如”5”,则相加的结果就变成了”55”(原始字符串值), 因为第一个操作数也会被转换为字符串。

​ ECMAScript 中最常犯的一个错误,就是忽略加法操作中涉及的数据类型。比如下面这个例子:

let num1 = 5;
let num2 = 10;
let message = "The sum of 5 and 10 is " + num1 + num2; 
console.log(message); // "The sum of 5 and 10 is 510"

​ 这里,变量 message 中保存的是一个字符串,是执行两次加法操作之后的结果。有人可能会认为 最终得到的字符串是”The sum of 5 and 10 is 15”。可是,实际上得到的是”The sum of 5 and 10 is 510”。这是因为每次加法运算都是独立完成的。第一次加法的操作数是一个字符串和一个数值(5),结果还是一个字符串。第二次加法仍然是用一个字符串去加一个数值(10),同样也会得到一个字符串。 如果想真正执行数学计算,然后把结果追加到字符串末尾,只要使用一对括号即可:

let num1 = 5;
let num2 = 10;
let message = "The sum of 5 and 10 is " + (num1 + num2); 
console.log(message); // "The sum of 5 and 10 is 15"

​ 在此,我们用括号把两个数值变量括了起来,意思是让解释器先执行两个数值的加法,然后再把结果追加给字符串。因此,最终得到的字符串变成了”The sum of 5 and 10 is 15”。

  1. 减法操作符

    减法操作符(-)也是使用很频繁的一种操作符,比如:

    let result = 2 - 1;

    与加法操作符一样,减法操作符也有一组规则用于处理 ECMAScript 中不同类型之间的转换。

    • 如果两个操作数都是数值,则执行数学减法运算并返回结果。
    • 如果有任一操作数是 NaN,则返回 NaN。
    • 如果是 Infinity 减 Infinity,则返回 NaN。
    • 如果是-Infinity 减-Infinity,则返回 NaN。
    • 如果是 Infinity 减-Infinity,则返回 Infinity。
    • 如果是-Infinity 减 Infinity,则返回-Infinity。
    • 如果是+0 减+0,则返回+0。
    • 如果是+0 减-0,则返回-0。
    • 如果是-0 减-0,则返回+0。
    • 如果有任一操作数是字符串、布尔值、null 或 undefined,则先在后台使用 Number()将其转换为数值,然后再根据前面的规则执行数学运算。如果转换结果是 NaN,则减法计算的结果是NaN。
    • 如果有任一操作数是对象,则调用其 valueOf()方法取得表示它的数值。如果该值是 NaN,则减法计算的结果是 NaN。如果对象没有 valueOf()方法,则调用其 toString()方法,然后再将得到的字符串转换为数值。

    以下示例演示了上面的规则:

    let result1 = 5 - true; // true被转换为1,所以结果是4
    let result2 = NaN - 1;  // NaN
    let result3 = 5 - 3; //2
    let result4 = 5 - ""; // ""被转换为0,所以结果是5
    let result5 = 5 - "2";  // "2"被转换为2,所以结果是3
    let result6 = 5 - null; // null被转换为0,所以结果是5