Skip to content

算术运算符有以下几类:

  • 基本算术:+ - * /
  • 正负:+ -
  • 取模(求余):%
  • 自增和自减:++ --
  • 求幂:**
js
var a = 1 + 2;
var b = 1 - 3;
var c = 2 * 6;
var d = 3 / 6;

我相信这四个基本的运算符是没有任何难度的,只有一些细节需要注意,唯一要强调的就是除法运算符,这里主要针对于那些学过其他编程语言的读者,在强类型编程语言中,两个整型相除,得到的也应该是整型,会对结果进行向下取整,例如 3/6 这个表达式,我们知道它的结果是 0.5,但强类型语言会将其向下取整为 0。但 JS 中并不存在这个问题,这里要做一个区分。

加号运算符也可用于字符串拼接,自行往下看

小数计算精度的问题

在计算机中,部分小数的计算是不精准的,我们可以用这样一个例子来验证:var a = 0.1+0.2;,此时 a 的值为 0.30000000000000004,为什么会有这么奇葩的结果,如果读者对这里出现的原因比较感兴趣,可以参考 浮点精度(float、double)运算不精确的原因_float为什么不准确-CSDN博客 ,这里暂且不提产生原因,读者只需要记住,在任何编程语言中,小数的计算都是不精准的,在开发中如果进行数据对比,就会出现足以致命的问题,例如 0.1+0.2 的值和 0.3 不同,基于这样的问题,读者在比较两个小数是否相等的时候就不能直接比较,应该用两个数相减,如果它们差的绝对值小于某个特别小的数,我们可以认为这两个数是相等的。

除数为 0 的情况

我们知道,在数学中,除数是不能为 0 的,在 JS 中,如果除数为 0,可能会出现两种情况,如果被除数不为 0,也就是类似于 1/0 这样的式子,得到的结果应该是正无穷,也就是 Infinity,当然如果是负数得到的就应该是 -Infinity,如果被除数也是 0,得到的结果是 NaN。
这个也很好理解,我们知道,分母绝对值越小,整个分式绝对值就越大,当分母绝对值趋向 0 并且分子也不为 0 的时候,整个分式的极限就是无穷大,所以一个不为 0 的数除以 0 得到的就是无穷大。在 JS 中,使用 Infinity 这个关键字来表示无穷大,这玩意儿本质上也是一个数字,JS 中的数字是有一个上限的,超过这个上限就会变成 Infinity,读者可以用 Number.MAX_VALUE 获取到 JS 中可以表示的最大数字,当超过这个数字的时候,JS 就会表达为 Infinity,我们可以使用 isFinite() 函数判断一个数是否是有限值,如果返回了 false,则表示这个数是 Infinity 或者 -Infinity 或者 NaN

NaN (not a number)

NaN 表示这不是一个数字,但本质上 NaN 也是一个数字,只不过是一个不正常的数字,例如 0/0 这个表达式的值就是 NaN,因为哪怕是 1/0 这种,我们也能猜出这是无穷大,但 0/0 哪怕在微积分中都是未定式,结果都是不确定的,但是两个数字相除的结果也必须是一个数字,所以我们就用 NaN 来表示这种不正常的数字,注意,NaN 本质上也是一个数字,只不过这个数字不正常,我们可以用 typeof 来验证:typeof NaN; 会返回 number。
如果读者有一定的编程基础,可能会考虑到这样的问题,NaN 既然是一个不正常的数字,参与运算的结果也必然不正常,所以我们就要避免让它参与运算,我们很多时候就要判断一个变量是不是 NaN,我们有两种判断方式,一个是 isNaN(),将变量传入,就可以返回这个值是不是 NaN,如果是 NaN 就会返回 true,否则返回 false,还有一种是 Number.isNaN() ,这两个函数的用法相同,但存在一些细微区别,读者只要记住一般情况下 Number.isNaN() 会更好就行了。
事实上,NaN 和任何数字的运算结果都会是 NaN

注:isInfinite(NaN) 返回值为 false,即 JS 认为 NaN 也不是有限的数字。

1/0 会返回 Infinity,typeof Infinity 会返回 number, 但 typeof 1/0 则会返回 NaN,这个看起来很矛盾,但并不难理解,在 typeof 1/0 这个表达式中,会先执行 typeof 1,这个表达式结果为 "number",这是一个字符串,此时将这个字符串除以 0,结果自然就是 NaN

以上介绍了加减乘除四个运算符,正负运算符其实也非常简单

js
var a = +1;//就是正一
var b = -1;//就是负一

取余运算符,就是 %,这个运算符的意思就是取余数,比如 5/2 就是商 2 余 1,比如 2/2 就是商 1 余 0。

js
var a = 2%2;//得到余数0
var b = 3%2;//得到余数1
var c = 5%3;//得到余数2
var d = -5%3;//得到余数-2
var e = 5%-3;//得到2

取模是一个典型的哈希算法,x%y 这个表达式的取值范围一定是 0~y-1,也就是说,对于任何的 x,我都可以通过对 y 取模的操作将其映射到 0~y-1 上,这在实际开发中非常有用。

取余运算结果的符号取决于被除数,和被除数的符号一样,和除数没有任何关系。取余运算的除数和被除数都可以是小数,但一般不建议使用小数。

取余运算符的用途非常多,目前阶段需要知道取余运算符可以判断是否整除,若 a % b == 0,则表示 a 可以被 b 整除。

取模和取余两个操作很多教程都是混用的,但这二者有一定区别,可以参考 10.取余和取模

求幂运算符 ** 是一个相对新一点的运算符,是 ES2016 才提出的一种运算符,以 chrome 浏览器为例,chrome 浏览器从 1 版本就支持了加减乘除和取余操作符,而求幂操作符直到 52 版本才被支持,所以在很多教程里并没有提及这个运算符。

这个运算符的功能就是求幂,比如 5**2 的值就是 5 的 2 次幂,也就是 25,比如 2**3 指的就是 2 的 3 次幂,也就是 8

在 JS 中其实提供了求幂运算的方法,放在了 Math 对象中,Math.pow(a,b) 基本等价于 a**b,但存在细微区别,目前阶段涉及不到。

一般来说我们只会在算术中使用算术运算,但在 JS 中允许其他类型的数据使用算术运算,并且会得到各种各样的结果,这里进行说明。

  • 使用除了加号以外的算术运算符,遇到非数字类型,都会将数据类型强制转换为数字类型再进行运算,最后的结果也一定是数字。
  • 对于加号运算符,如果两边都没有字符串和对象,则按照上面的规则进行计算。
  • 对于加号运算符,如果加号其中一项有字符串,则这个加号运算符就表示字符串拼接,就不再是数学运算了,例如 "1"+2 结果为 "12",可以看到,一旦加号运算符有一边表示是字符串,不管另一边是什么,都会将其转换为字符串,然后进行字符串拼接,最后得到的结果也一定是字符串,""+true 得到的结果就是 "true"。
  • 对于加号运算符,我们知道,如果是一个对象加上字符串,则会将对象转换为字符串,再进行字符串拼接。如果一个是对象,另一个不是字符串,也会将对象先转换为字符串,然后再进行字符串拼接,例如 ({}+123) 得到的结果就是 "[object Object]123",

这种奇奇怪怪的东西对开发基本没有实质性帮助,唯一有用的可能就是以下两个技巧
我们可以使用 +a,使用正号运算符,将变量 a 强制转换为数字类型。
我们可以使用 ""+a,使用空串拼接上一个变量,将这个变量强制转换为字符串类型。

JS 的数据转换规则

其他类型转换为数字类型:

  • true -> 1
  • false -> 0
  • 数字字符串,例如"123","1.2" -> 正确转换为正确数字
  • 不正确的数字字符串,例如"abc","12. a" -> NaN
  • 空字符串"" -> 0
  • "Infinity" -> Infinity (Infinity 字符串可以正确转换)
  • null -> 0
  • undefined -> NaN
  • 对象 -> NaN

对于对象类型转换为数字,会将对象类型转换为字符串类型,再将字符串转换为数字,由于对象类型转换为字符串固定为 "[object Object]",在转为数字就是 NaN。

其他类型转换为字符串

  • 数字类型 -> 直接正常转
  • true -> "true"
  • false -> "false"
  • null -> "null"
  • undefined -> "undefined"
  • 对象 -> ""

其他类型转布尔
null, undefined, false, NaN,"", 0 转为 false,其余均为 true

注:在字符串转数字的时候,会忽略到字符串前后的空格,例如 " 123 " 转换结果还是 123,但并不会忽略中间的空格,例如 "12 3" 转换结果就是 NaN,所以我们现在就知道 " " 转换结果其实还是 0

在 JS 中存在两个 0,分别是+0 和-0,这是 JS 设计上的问题,这并不会影响运算。

练习 1:

js
console.log(1+2*3);//7
console.log(1+3%2);//2
console.log(""+3%2);//"1"
console.log(+""+3%2);//1
console.log(+{}+"");//"NaN"
console.log(100%4/0);//NaN
console.log(undefined+{}+123);//"undefined[object Object]123"
console.log(1+""+2+3);//"123"
conosle.log({}*null);//NaN
console.log(+""+100);//101

练习 2:
温度转换器,将摄氏温度 C 转换为华氏温度 F

js
var C = 36;//存放设置温度
var F = (9/5)*C + 32;//华氏温度
console.log(F);

利息计算器,三个变量分别存放本金,月数,年利率,计算利息

js
var principal = 10000;//本金
var annualInterestRate = 0.045;//年利率
var months = 18;//月数
var monthsInterestRate = 0.045/12;//计算出月利息
var interest = principal * monthsInterestRate * mounths;//每月利息乘以月数
console.log(interest);

以笔记为镜,可以知得失