原文地址:https://wangdoc.com/javascript/
概述
JavaScript共提供10个算术运算符:
- 加法运算符:x + y
- 减法运算符:x - y
- 乘法运算符:x * y
- 除法运算符:x / y
- 指数运算符:x ** y
- 余数运算符:x % y
- 自增运算符:x++或者++x
- 自减运算符:x--或者--x
- 数值运算符:+x
- 负数值运算符:-x
加法运算符
基本规则
JavaScript允许非数值的相加。
true + true // 2
1 + true // 2
比较特殊的是,如果是两个字符串相加,这时加法运算符会变成连接运算符,返回一个新的字符串,将两个原字符串连接在一起。如果一个运算子是字符串,另一个运算子是非字符串,这时非字符串会转成字符串,再连接在一起。
1 + 'a' // "1a"
false + 'a' // "falsea"
加法运算符是在运行时决定,到底是执行相加还是执行连接。也就是说,运算子的不同,导致了不同的语法行为,这种现象称为重载(overload)。
"3" + 4 + 5 // "345"
3 + 4 + "5" // "75"
除了加法运算符,其他算术运算符都不会发生重载。它们的规则是:所有的运算子一律转为数值,再进行相应的数学运算。
对象的相加
如果运算子是对象,必须先转成原始类型的值,然后再相加。
对象转成原始类型的值规则如下:
首先,自动调用对象的valueOf方法。一般来说,对象的valueOf方法总是返回对象自身。
再调用对象的toString方法,将其转为字符串。
var obj = { p: 1 };
obj.valueOf(); // { p: 1 }
obj.valueOf().toString(); // "[object Object]"
对象的toString方法默认返回[object Object],所以就得到了最前面的那个例子的结果。
知道这个规则后,就可以自己定义valueOf方法或者toString方法,得到想要的结果。
但是,如果运算子是一个Date对象的实例,那么会优先执行toString方法。
var obj = new Date();
obj.valueOf = function() { return 1; };
obj.toString = function() { return "hello"; };
obj + 2 // "hello2"
余数运算符
余数运算符(%)返回前一个运算子被后一个运算子除,所得的余数。需要注意的是,运算结果的正负号由第一个运算子的正负号决定。
-1 % 2 // -1
1 % -2 // 1
所以判断奇偶数,可以先使用绝对值函数。
// 错误的写法
function isOdd(n) {
return n % 2 === 1;
}
isOdd(-5) // false
isOdd(-4) // false
// 正确的写法
function isOdd(n) {
return Math.abs(n % 2) === 1;
}
isOdd(-5); // true
isOdd(-4); // false
数值运算符,负数值运算符
数值运算符(+),作用在于可以将任何值转为数值(与Number函数的作用相同)。
+true // 1
+[] // 0
+{} // NaN
注意NaN也是数值。
负数值运算符(-),也同样具有将一个值转为数值的功能,只不过得到的值正负相反,连着用两个负数值运算符,等同于数值运算符。
var x = 1;
-x // -1
-(-x) // 1
指数运算符
指数运算符()完成指数运算。指数运算符是右结合,而不是左结合。**
2 ** 3 ** 2
// 相当于
2 ** (3 ** 2)