【JSRedBook⁰⁹】一元操作符

引子

本文讲述了 ECMA-262 中可用于操作数据值的操作符之一元操作符

ECMAScript 中的操作符是独特的,因为它们可用于各种值,包括字符串、数值、布尔值,甚至还有对象;在应用给对象时,操作符通常会调用 valueOf()toString() 方法来取得可以计算的值。

一元操作符

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

递增与递减操作符

有两个版本,分别是前缀版(位于操作的变量前面)和后缀版(位于要操作的变量后面);

前缀版操作符

前缀递增操作符会给数值加 1,把两个加号(++)放到变量前头即可,如下所示:

 let age = 29;
 ++age;  // 等同于 age = age + 1
复制代码

通过前缀递增操作符简化语法把 age 的值变成了 30(给之前的值 29 加 1),下面我们来看递减:

使用前缀递减操作符,只要把两个减号(–)放到变量前头即可,如下所示:

 let age = 29;
 --age;  // 等同于 age = age - 1;
复制代码

执行操作后,变量 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
 console.log(num1); // 1
复制代码

后缀版操作符

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

 let age = 29; 
 age++; 
复制代码

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

 let num1 = 2; 
 let num2 = 20; 
 let num3 = num1-- + num2; // num3: 22
 let num4 = num1 + num2; // num4: 21
复制代码

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

递增递减规则

这 4 个操作符可以作用于任何值,意思是不限于整数——字符串、布尔值、浮点值,甚至对象都可以。

递增和递减操作符遵循如下规则:

  • 对于字符串,如果是有效的数值形式,则转换为数值再应用改变;变量类型从字符串变成数值
  • 对于字符串,如果不是有效的数值形式,则将变量的值设置为 NaN ;变量类型从字符串变成数值
  • 对于布尔值,如果是 false,则转换为 0 再应用改变;变量类型从布尔值变成数值
  • 对于布尔值,如果是 true,则转换为 1 再应用改变;变量类型从布尔值变成数值
  • 对于浮点值,加 1 或减 1。
  • 如果是对象,则调用其 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
复制代码

一元加与减

一元加和减操作符;一元加由一个加号(+)表示,放在变量前头,对数值没有任何影响:

 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 
复制代码

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

 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 
复制代码

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

总结

一元运算符是 ECMAScript 中最简单的运算符,它只有一个参数,即要操作的对象或值

最主要的还是前缀与后缀的区别,前缀是求值前改值,后缀是求值后改值

简单过一下转换规则:

  • 如果是有效的字符串,则转换数值再应用改变;
  • 如果是无效的字符串,则将变量的值设置为NaN
  • 如果布尔值的值为true,则转化为1;若为 false ,则转换为 0
  • 对于浮点值,加1 或 减1
  • 如果是对象,调用 valueOf() 方法取到可以操作的值;若为 NaN,则调用 toString()
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享