一元操作符

​ 只操作一个值的操作符叫一元操作符(unary operator)。一元操作符是 ECMAScript 中最简单的操作符。

递增/递减操作符

​ 递增和递减操作符直接照搬自 C 语言,但有两个版本:前缀版和后缀版。顾名思义,前缀版就是位于要操作的变量前头,后缀版就是位于要操作的变量后头。前缀递增操作符会给数值加 1,把两个加号(++)放到变量前头即可:

let age = 29;
++age;

​ 在这个例子中,前缀递增操作符把 age 的值变成了 30(给之前的值 29 加 1)。因此,它实际上等于如下表达式:

let age = 29;
age = age + 1;

​ 前缀递减操作符也类似,只不过是从一个数值减 1。使用前缀递减操作符,只要把两个减号(—) 放到变量前头即可:

let age = 29;
--age;

​ 执行操作后,变量 age 的值变成了 28(从 29 减 1)。

​ 无论使用前缀递增还是前缀递减操作符,变量的值都会在语句被求值之前改变。(在计算机科学中, 这通常被称为具有副作用。)请看下面的例子:

let age = 29;
let anotherAge = --age + 2;
console.log(age); // 28 
console.log(anotherAge); // 30

​ 在这个例子中,变量 anotherAge 以 age 减 1 后的值再加 2 进行初始化。因为递减操作先发生,所以 age 的值先变成 28,然后再加 2,结果是 30。

​ 前缀递增和递减在语句中的优先级是相等的,因此会从左到右依次求值。比如:

let num1 = 2; 
let num2 = 20;
let num3 = --num1 + num2;
let num4 = num1 + num2;
console.log(num3); // 21 
console.log(num4); // 21

​ 这里,num3 等于 21 是因为 num1 先减 1 之后才加 num2。变量 num4 也是 21,那是因为加法使用的也是递减后的值。

​ 递增和递减的后缀版语法一样(分别是++和—),只不过要放在变量后面。后缀版与前缀版的主要区别在于,后缀版递增和递减在语句被求值后才发生。在某些情况下,这种差异没什么影响,比如:

let age = 29;  
age++;

​ 把递增操作符放到变量后面不会改变语句执行的结果,因为递增是唯一的操作。可是,在跟其他操作混合时,差异就会变明显,比如:

let num1 = 2;
let num2 = 20;
let num3 = num1-- + num2; 
let num4 = num1 + num2;
console.log(num3); // 22
console.log(num4); // 21

​ 这个例子跟前面的那个一样,只是把前缀递减改成了后缀递减,区别很明显。在使用前缀版的例子 中,num3 和 num4 的值都是 21。而在这个例子中,num3 的值是 22,num4 的值是 21。这里的不同之处 在于,计算 num3 时使用的是 num1 的原始值(2),而计算 num4 时使用的是 num1 递减后的值(1)。

​ 这 4 个操作符可以作用于任何值,意思是不限于整数-----字符串、布尔值、浮点值,甚至对象都可以。递增和递减操作符遵循如下规则。

  • 对于字符串,如果是有效的数值形式,则转换为数值再应用改变。变量类型从字符串变成数值

  • 对于字符串,如果不是有效的数值形式,则将变量的值设置为 NaN 。变量类型从字符串变成数值

  • 对于布尔值,如果是 false,则转换为 0 再应用改变。变量类型从布尔值变成数值

  • 对于布尔值,如果是 true,则转换为 1 再应用改变。变量类型从布尔值变成数值

  • 对于浮点值,加 1 或减 1。

  • 如果是对象,则调用其(第 5 章会详细介绍的)valueOf()方法取得可以操作的值。对得到的值应用上述规则。如果是 NaN,则调用 toString()并再次应用其他规则。变量类型从对象变成数值

    下面的例子演示了这些规则:

let s1 = "2";
let s2 = "z";
let b = false;
let f = 1.1;
let o = {
  valueOf() {
    return -1;
  },
};
s1++; // 值变成数值3
s2++; // 值变成NaN
b++; // 值变成数值 1
f--; // 值变成 0.10000000000000009(因为浮点数不精确)
o--; // 值变成-2

一元加和减

​ 一元加和减操作符对大多数开发者来说并不陌生,它们在 ECMAScript 中跟在高中数学中的用途一 样。一元加由一个加号(+)表示,放在变量前头,对数值没有任何影响:

let num = 25;
num = +num; 
console.log(num); // 25

​ 如果将一元加应用到非数值,则会执行与使用 Number()转型函数一样的类型转换:布尔值 false 和 true 转换为 0 和 1,字符串根据特殊规则进行解析,对象会调用它们的 valueOf()和/或 toString() 方法以得到可以转换的值。

​ 下面的例子演示了一元加在应用到不同数据类型时的行为:

let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let f = 1.1;
let o = {
  valueOf() {
    return -1;
  },
};
s1 = +s1; // 值变成数值1
s2 = +s2; // 值变成数值1.1
s3 = +s3; // 值变成NaN
b = +b; // 值变成数值 0
f = +f; // 不变,还是 1.1
o = +o; // 值变成数值-1

​ 一元减由一个减号(-)表示,放在变量前头,主要用于把数值变成负值,如把 1 转换为-1。示例 如下:

let num = 25;
num = -num; 
console.log(num); // -25

​ 对数值使用一元减会将其变成相应的负值(如上面的例子所示)。在应用到非数值时,一元减会遵循与一元加同样的规则,先对它们进行转换,然后再取负值:

let s1 = "01";
let s2 = "1.1";
let s3 = "z";
let b = false;
let f = 1.1;
let o = {
  valueOf() {
    return -1;
  },
};
s1 = -s1; // 值变成数值-1
s2 = -s2; // 值变成数值-1.1
s3 = -s3; // 值变成NaN
b = -b; // 值变成数值 0
f = -f; // 变成-1.1
o = -o; // 值变成数值 1

​ 一元加和减操作符主要用于基本的算术,但也可以像上面的例子那样,用于数据类型转换。