JS中的比大小
JS中的比大小
1.都是数字
这个最简单了,我们直接进行数值比较就好了。JS 中数字类型(number)存储的方式只有一种,在其他语言中往往叫做双精度类型。算下来一共使用到了 64 个 bit(1 位符号位 + 11位指数位 + 52 位有效位),也就是 8 byte。但是浏览器可能会对整数的存储做一些优化,并不一定占用这么多。
2.都是字符串
字符串的规则是逐个比较字符串中每个字符的编码,我们可以使用 String 内置的 charCodeAt来查看某个字符对应的编码。
"abc".charCodeAt(0)
有个很容易犯的错误,大写的字母会比小写的字符编码小。所以 ‘Banana’ 是小于 ‘banana’,大家在比较字符串大小的时候要把这一点额外考虑进去,如果这一点对你有影响的话,可以考虑把字符串全都小写化,再比较大小。
3. 任意一个是数字
优先把另外一个转为数字,应用规则 1。
4. 任意一个是布尔值
将其转为数值后,应用上面的规则。
5. 某一个是对象
调用 valueOf 方法,取得的结果应用上面的几条规则进行比较;那如果没有 valueOf 呢?就调用 toString,取得的结果再按上面的规则进行比较。
比较操作符的规则就是上面这五条。
聪明的你可能发现了,在类型不相同的两个元素进行比较时,可能会包含隐式类型转化,这是个巨大的坑!
比如:'a' < 1 和 'a' > 1 结果都会返回 false ,这是因为我们会先应用规则 3,先想办法把字符串 ‘a’ 转化为了数字类型,得到的结果是 NaN ,而 NaN 和谁比较都会返回 false。
这一点提醒我们,以后在比较大小时,最好只比较相同类型的变量,以免引发难以察觉到 BUG。 不过在全民 TypeScript 的时代,这一点也可以不用特别注意。
回归主题,我们的 Date 对象为什么能比较大小呢?因为 JS 帮我们重写了它的 valueOf 方法。它返回的结果是 Date 对象的毫秒表示,接下来我们就应用上述的规则 5 就好了。
new Date().valueOf() // 1610266969084
PS: 毫秒表示是当前 Date 对象表示的时间距离 UNIX 纪元(1970 年 1 月 1 日)差了多少毫秒。
new Date('2021-01-10') < new Date('20201-01-11')
// 1610236800000 < 1610323200000
依照这个原理,如果我们想让我们在自定义对象中实现大小的比较,直接重写 valueOf 方法就好了。
class AppleTree {
constructor(age) {
this.age = age
}
valueOf() {
return this.age
}
}
new AppleTree(1) < new AppleTree(10) // true
比较 Date 对象只是个引子,通过它我们搞懂了 JS 中比较操作符的原理,再也不怕在这里踩坑了。
作者:徐徐转载请注明出处