前言
昨天在朋友圈看到了这张有趣的图

那我们今天就来讲讲这个图吧
正文
Typeof
1 | typeof NaN |
因为typeof只能返回下面的东西

所以它只能返回个number了,而且NaN一般是在想把什么东西转化成number类型但是转化失败了才会出现的结果,某种意义上还是说的过去的

浮点数精度
1 | 9999999999999999 // 10000000000000000 |
JavaScript 中的数字按照 IEEE 754 的标准,使用 64 位双精度浮点型来表示,而我们知道,想用有限的位来表示无穷的数字,显然是不可能的,因此会出现一些列精度问题:
- 浮点数精度问题,比如
0.1 + 0.2 !== 0.3 - 大数精度问题,比如
9999 9999 9999 9999 == 1000 0000 0000 0000 1 - toFixed 四舍五入结果不准确,比如
1.335.toFixed(2) == 1.33
有三种思路来解决这个问题
- 考虑到每次浮点数运算的偏差非常小(其实不然),可以对结果进行指定精度的四舍五入,比如可以
parseFloat(result.toFixed(12)); - 将浮点数转为整数运算,再对结果做除法。比如0.1 + 0.2,可以转化为
(1*2)/3。 - 把浮点数转化为字符串,模拟实际运算的过程。
不过其实只有第三种是完全可行的
先来看第一种方案,在大多数情况下,它可以得到正确结果,但是对一些极端情况,toFixed 到 12 是不够的,比如:
1 | 210000 * 10000 * 1000 * 8.2 // 17219999999999.998 |
第二种方案也有一些问题,并不是完全可行
1 | // 这两个浮点数,转化为整数之后,相乘的结果已经超过了 MAX_SAFE_INTEGER |
所以,最终考虑使用第三种方案,目前已经有了很多较为成熟的库
这些库不仅解决了浮点数的运算精度问题,还支持了大数运算,并且修复了原生toFixed结果不准确的问题。
Math.max和Math.min
问就是看文档,其实没啥好记的,当成特殊情况下了解一下就可以了


奇怪的 + - !
1 | [] + [] // "" |
这是把+丢到一个表达式前面会发送的事情
简单来说就是会调用Number()把表单式转化为number类型

这是传统意义上的+会发生的过程

翻译一下
- 把左右两边转化成原始类型
- 如果一边是字符串,把另一边转成字符串做拼接
- 否则把两边都转成数字进行
+运算
这是把-丢到一个表达式前面会发送的事情

简单来说就是调用Number()转成数字然后取反(正负的反)
这是传统意义上的-会发生的过程

翻译一下:把两边都转成数字进行运算
然后这是!会发生的

简单来说就是调用Boolean()然后取反
顺带一提,这个表达式,你以为是对象加数组
1 | {} + [] |
其实是这样的
1 | {} |
上面的对象会被解析成一个代码块,然后只剩下+[],而Number([])的结果就是0
再顺带一提,这个东西
1 | (!+[]+[]+![]).length |
运行起来其实是这样的
1 | (!+[] + [] + ![]).length |
== 和 ===
==看这篇:https://www.sakura-snow.com/archives/142
===就是在==的基础上不进行类型转化而已,类型不一样直接返回false
