专栏首页全沾开发(huā)JavaScript中的比较运算符

JavaScript中的比较运算符

JavaScript中的比较运算符

JavaScript中的比较运算符粗略的可以分为两种:

  1. 相等运算符(==、===、!==)这些
  2. 关系运算符(>、<、>=) 在平时开发中,基本不会太关注这两者的差异,我们几乎总是可以获取到我们想要的结果-。-

前几天在群里一个小伙伴问了个问题:

console.log(null > 0) // => false
console.log(null < 0) // => false
console.log(null == 0) // => false

console.log(null >= 0) // => ?

最后一个null >= 0的结果为true。 刚看到这个代码的时候,下意识地会认为结果应该也是false,毕竟上边标明了三种情况都为false。 然而这个就露出了相等运算符关系运算符两者执行的差异。

在相等运算符中,如果是非严格相等,则会尝试将两边的值转换为相同类型进行比较。 在关系运算符中,会尝试将运算符两边的值转换为Number再进行比较。

所以在执行null >= 0的时候null被转换为Number随后值就变为了0,所以第四个运算符实际的执行为0 >= 0

觉得这个题挺有意思的,所以就去翻了下文档,看看这几个比较运算符在执行的时候都做了些什么。

相等运算符

相等运算符有四个,==!====!==,前两个会对运算符两边的表达式进行类型转换,试图转换为相同的类型。

==!=

执行时会先检查两者类型是否一致,如一致则相当于调用===!== 随后判断两者是否都为nullundefined,如果均为这两个值,则会直接返回true

接下来就会进行一些类型转换,绝大多数情况是会转换为Number,但是主要转换类型的依赖还是在于运算符左侧表达式的类型。

如果一边类型为String另一边类型为Number,则会将String转换为Number对两者进行比较。 如果其中一个为Boolean,则会将该表达式转换为Number

上边的是一些比较常规的类型转换,但是如果都不满足上边的条件,后续还会有其他的转换。 如果其中一个为Object,另一个类型为NumberString或者是Symbol中的任意一个。 则会获取Object的原始值,然后对两者进行比较。

然后表格中对Object类型又有一些额外的处理

在最后我们可以看到,会针对Object类型的变量进行调用valueOftoString 而两个函数调用的顺序取决于上边一些判断的过程,目前还木有找到会先执行toString的例子。。。(因为原始类型无法直接添加toStringvalueOf事件的代理)

我们可以用Object.assign来实现某个对象的toStringvalueOf方法来观察执行的过程。

如果valueOf返回值还是Object的话,则会继续调用toString

如果两个函数都返回Object,这时就会抛出一个类型异常的错误

===!==

相较=====的逻辑就很清晰了,因为没有了不同类型之间的转换,就是拿到两个表达式进行比较即可。

首先就是获取两侧表达式的类型,如果不同则返回false,相同则进行后续的比较。

关于Number类型步骤的描述,有一点我很是疑惑,就是关于+0 === -0,因为一元正负运算符的优先级肯定是高于===的,不知为何会写在这里-.-

关系运算符

关系运算符的执行过程,是尽可能的将两边的表达式转换为Number进行比较。(也确实,其他类型木有什么可比性的)

运算符刚开始会尝试将两侧表达式转换为原始值,并且在转换的过程中会优先选择转换为Number类型。

转换完成后,如果两边表达式都为String,则会先判断一侧表达式是否包含另一侧。 例如:

'abc' > 'ab' // abc 包含 ab 所以 abc 比 ab 大,结果为true

如果两者不为包含关系,则会从第一个字符开始获取对应的Unicode编码,来进行比大小,如果大小相同,则顺移至下一位。

其余情况下,则会将两侧表达式直接转换为Number求值。

Number(true)
Number({})
Number(undefined)
Number(null)
// ...

当任意一个结果为NaN时,运算符的结果都为false(而且文档中给出的,返回值为undefined,并不是false。。。)

然后针对<><=>=进行各自的判断。

所以到最后就解释了,为什么那个问题的null >= 0true。 因为关系运算符是会将值转换为Number来进行比较的。 而相等运算符只在极少数的情况下会将值转换为Number来进行比较(例如:一个为Number另一个为String

参考文档

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • JavaScript中的比较运算符

    最后一个null >= 0的结果为true。 刚看到这个代码的时候,下意识地会认为结果应该也是false,毕竟上边标明了三种情况都为false。 然而这个就露出...

    贾顺名
  • 使用TS+Sequelize实现更简洁的CRUD

    如果是经常使用Node来做服务端开发的童鞋,肯定不可避免的会操作数据库,做一些增删改查(CRUD,Create Read Update Delete)的操作,如...

    贾顺名
  • Chrome设置断点的各种姿势

    Chrome设置断点的各种姿势 最近在翻看Chrome devtools的文档,刚看到了关于断点调试这里,感觉发现了新大陆-。- 本...

    贾顺名
  • JavaScript中的比较运算符

    最后一个null >= 0的结果为true。 刚看到这个代码的时候,下意识地会认为结果应该也是false,毕竟上边标明了三种情况都为false。 然而这个就露出...

    贾顺名
  • Python 中的神秘运算符

    今天我们来讲讲 Python 里一个不为众人所知的运算符。你可能会觉得疑惑:还有我不知道的运算符?别急着下结论,先往下看看再说。

    Crossin先生
  • Swift解读专题三——基础运算符 原

            运算符是编程语言不可缺少的一个部分,Swift中除了支持C中的运算符外,还提供了一些更加强大的运算符功能,例如取余符%可以用来计算浮点数,另外新...

    珲少
  • Dimple在左耳听风ARTS打卡(二十)

    今天的内容干货满满,还烦请大家仔细观看。首先真是一个值得纪念的日子,历时5个月,终于把《Head First设计模式》这本书给二刷完成了。想起第一次看的时候,也...

    程序员小跃
  • 2020边缘计算:国外10家初创企业能否掀起新的波澜

    根据Gartner的数据,到2025年,大约75%的数据将需要在边缘进行分析和处理,Gartner还认为,到2023年,超过50%的大型企业将部署至少6个边缘计...

    SDNLAB
  • [linux][network]ICMP协议分析

    前言: ICMP比较基础,说简单不简单,说难不难。 简单在于字段少,不能携带用户数据,没什么地方可以玩出太多花样;一般和它相关的就是ping和tracerout...

    皮振伟
  • 大数据之脚踏实地学08--搭建Hadoop集群【2】

    在《大数据之脚踏实地学07--搭建Hadoop集群【1】》中,讲解的是虚拟机的配置(包括网络设置、主机名修改和克隆等),文中我们在VMware中虚拟了3台计算机...

    1480

扫码关注云+社区

领取腾讯云代金券