03-算术运算符
5.2 算术运算符
JavaScript的算术运算符如表5-1。
| 运算符 | 说 明 | 示 例 | | :----- | :----- | :----- | :----- | :----- | | + | 加法(以及字符串连接) | 3 + 2 // 5 | | − | 减法 | 3 − 2 // 1 | | / | 除法 | 3/2 // 1.5 | | | 乘法 | 32 // 6 | | % | 取余数 | 3%2 // 1 | | − | 一元负号 | −x // 负x; 如果x是5,−x就是−5 | | + | 一元正号 | +x // 如果x不是数字,会试图将它转换成数字 | | ++ | 前置自增运算符 | ++x // 给x的值加1,并计算新的值 | | ++ | 后置自增运算符 | x++ // 给x的值加1,并在x自增前计算它的值increments | | -- | 前置自减运算符 | --x // 给x的值减1,并计算新的值 | | -- | 后置自减运算符 | x-- // 给x的值减1,并在x自减前计算它的值 |
记住,JavaScript中所有的数字都是双精度的,这意味着整数做算术运算的时候(如 3/2 ),也有可能会返回小数( 1.5 )。
减法和一元否定都使用相同的符号(−),那么JavaScript是如何区分它们的呢?这个问题的答案非常复杂,超出了本书的范围。重点是要知道一元否定的运算优先级高于减法运算:
const x = 5;
const y = 3 - -x; // y 的值为 8
一元正号的优先级也高于加法。它是一个不常用的运算符。该运算符通常是强制将字符串转换成数字,或者调整那些否定的值:
const s = "5";
const y = 3 + +s; // y is 8; 如果不使用一元加号运算符,结果为字符串"35"
// 使用不必要的一元加号运算符将代码排成一行
const x1 = 0, x2 = 3, x3 = -1.5, x4 = -6.33;
const p1 = -x1*1;
const p2 = +x2*2;
const p3 = +x3*3;
const p3 = -x4*4;
注意,在这些例子中,特意让一元否定、一元正号跟变量结合在一起使用。因为如果将它们直接跟数字一起使用,减号就会变成数字的一部分,这样就不是一个严格意义上的运算符了。
余数运算符返回除过之后的余数。比如,表达式x % y,返回的结果是被除数x除以除数 y 后的余数。例如, 10 % 3 结果为1(10是3的3倍余1)。注意,负数取余的结果会带上被除数的符号,而不是除数的,这样就防止这个运算符成为一个真正的模运算符。然而,余数运算符通常不仅用在整数上,在JavaScript中,它也可以用在小数上。例如, 10 % 3.6 等于 3 (10是3.6的两倍余了2.8)。
自增运算符(++)实际上是将赋值和加法运算合二为一了。同样,自减运算符是赋值和减法运算的结合体。这是两个很有用的快捷方式,但要谨慎使用。因为如果将它们隐藏在一个表达式的深处,其副作用可能很难被察觉(变量被更改了)。理解前置和后置运算符的区别很重要。前置运算符修改了变量,表达式的值是修改后的值;后置运算符也修改了变量值,但是表达式的值没有变。下面看看读者是否能够猜出下面表达式的值(提示:自增和自减运算符的优先级高于加法运算符,在这个例子中,按照从左到右的顺序计算它们的值):
let x = 2;
const r1 = x++ + x++;
const r2 = ++x + ++x;
const r3 = x++ + ++x;
const r4 = ++x + x++;
let y = 10;
const r5 = y-- + y--;
const r6 = --y + --y;
const r7 = y-- + --y;
const r8 = --y + y--;
试着在JavaScript控制台中运行这些代码,看看是否能猜对 r1 到 r8 的值,以及x和y的值在每一步的变化。如果在做这个练习时遇到问题,试着把它们写在一张纸上,根据运算顺序添加括号,然后按照顺序执行运算操作,例如:
let x = 2;
const r1 = x++ + x++;
// ((x++) + (x++))
// ( 2 + (x++)) 从左到右计算; x的值为 3
// ( 2 + 3 ) x 的值变为 4
// 5 结果为 5; x 的值为4
const r2 = ++x + ++x;
// ((++x) + (++x))
// ( 5 + (++x)) 从左到右计算; x的值为 5
// ( 5 + 6 ) x 的值变为 6
// 11 结果为11; x 的值为6
const r3 = x++ + ++x;
// ((x++) + (++x))
// ( 6 + (++x)) 从左到右计算; x的值为 7
// ( 6 + 8 ) x的值变为 8
// 14 结果为14; x 的值为8
//
// ... 等等