|
|
51CTO旗下网站
|
|
移动端

JavaScript 中的 4 个相等比较算法的介绍

JavaScript 运算中,一共包含 4 个相等比较算法:抽象相等比较;严格相等比较;SameValueZero;SameValue。

作者:zhangbao90s来源:掘金|2019-11-07 13:42

【线上直播】11月21日晚8点贝壳技术总监侯圣文《数据安全之数据库安全黄金法则》

JavaScript 运算中,一共包含 4 个相等比较算法:

  • 抽象相等比较
  • 严格相等比较
  • SameValueZero
  • SameValue

可以这么说,只要你做过相等比较,你就在使用四个算法中的一个。因为这些算法部署在了涉及到相等比较的操作符或方法中。

参见下表:

怎样区分这些算法的不同呢,可以从两方面切入:

  1. 是否会发生类型转换
  2. 对 NaN、-0、+0(即 0) 这些值是否存在特殊处理

下面给出一个总结:

就是说,抽象相等比较算法会发生类型转换,SameValue 算法不会特殊对待 NaN、-0、+0 这些值。

类型转换如何进行的?

上面讨论的四种算法中,只有“抽象相等比较算法”会发生类型转换。发生类型转换的前提是:比较的两个值类型不同,而且转换结果是数值。

举个例子:

  1. 1 == 1 // true(未发生类型转换) 
  2. '1' == 1 // true(发生了类型转换) 

第一个比较为 true,好理解;第二个就不一样了,会发生类型转换——将非数字值转为数字:'1' 跟 1 比较,两者类型不同,'1' 是字符串,因此会先转为数字——也就是 1(Number('1')),结果变为两个 1 在一起比较,结果就是 true 了。

“抽象相等比较算法”还有一个比较怪癖的地方,在于规范中定义 null == undefined 返回结果为 true。按理说应该发生类型转换,再进行比较的,比较结果应为 false(null 转为 0,undefined 转为 NaN,两者不等)。

JavaScript 中的 4 个相等比较算法的介绍

规范中对抽象相等比较算法搞了一个“小怪癖”:定义 null 和 undefined 的比较结果为 true

我猜想,这一定义可能是为了保证向前兼(tián)容(kēng),因此,我们记住即可。除此之外的其他情况,都按照类型转换后的比较结果为准。

NaN、-0 和 +0 是如何被特殊处理的?

ES2015 标准出版之前,是没有 SameValueZero 和 SameValue 这两个算法的。也就是说只有抽象相等比较和严格相等比较这两个算法:这两个算法有点问题——就是不能区分 NaN 以及 +0 和 -0。因此在 ES2015 之前,我们会遭遇这样的比较结果:

  1. NaN === NaN // false 
  2. +0 === -0 // true 
  3. [NaN].indexOf(NaN) // -1 
  4. [0].indexOf(-0) // -1 

NaN 与自身不相等,+0 等于 -0。在意识中,我们可能接受不了“NaN 与自身不相等”的结果,但是能够理解“+0 等于 -0”(都是 0 嘛),但是在某些符号位具有含义的场景中——- 表示向左,+ 表示向右,那么区分 +0 等于 -0 就有意义了。

基于此,ES2015 中引入了 SameValue 算法,Object.is() 方法内部就是使用此算法,比较两个值是否相等。

  1. Object.is(NaN, NaN) // true 
  2. Object.is(0, -0) // false 

SameValueZero 算法,通过名称我们可能就猜到,与 SameValue 算法的区别,仅仅是对“零”的态度上——SameValueZero 算法不能区分 +0 和 -0。

就是说:

  1. var array = [NaN, -0] 
  2. array.includes(NaN) // true 
  3. array.includes(0) // true 

array.includes(0) 的结果没有返回 false,是因为其内部使用的 SameValueZero 算法不能区分 +0 和 -0。

【编辑推荐】

  1. 2019全球程序员薪酬报告:软件开发比机器学习抢手!40岁后收入下滑
  2. 你可能错过的现代 JavaScript 特性
  3. JavaScript基础——你真的了解JavaScript吗?
  4. Java、Web 和移动程序员学习的 12 个框架
  5. 2019年开发人员应该学习的10个JavaScript框架
【责任编辑:华轩 TEL:(010)68476606】

点赞 0
分享:
大家都在看
猜你喜欢

订阅专栏+更多

骨干网与数据中心建设案例

骨干网与数据中心建设案例

高级网工必会
共20章 | 捷哥CCIE

374人订阅学习

中间件安全防护攻略

中间件安全防护攻略

4类安全防护
共4章 | hack_man

136人订阅学习

CentOS 8 全新学习术

CentOS 8 全新学习术

CentOS 8 正式发布
共16章 | UbuntuServer

282人订阅学习

读 书 +更多

精通Spring 2.0

本书是关于Spring 2.0的权威教程,是Java/Java EE开发者必备的参考书。本书详尽系统地介绍了Java EE的基础知识、Spring 2.0的各种功能,以...

订阅51CTO邮刊

点击这里查看样刊

订阅51CTO邮刊

51CTO服务号

51CTO官微