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

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

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

参见下表:

算法 使用了此算法的地方(部分) 抽象相等比较 == 运算符 严格相等比较 === 运算符、Array.prototype.indexOf 方法 SameValueZero String.prototype.includes、Array.prototype.includes 方法 SameValue Object.is 方法 怎样区分这些算法的不同呢,可以从两方面切入:

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

下面给出一个总结:

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

类型转换如何进行的?

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

举个例子:

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

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

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

规范中对抽象相等比较算法搞了一个“小怪癖”:定义 null 和 undefined 的比较结果为 true我猜想,这一定义可能是为了保证向前兼(tián)容(kēng),因此,我们记住即可。除此之外的其他情况,都按照类型转换后的比较结果为准。

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

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

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

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

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

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

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

就是说:

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

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

参考链接

  • Equality comparisons and sameness, by MDN

我自己是一名从事了多年开发的web前端老程序员,目前辞职在做自己的web前端私人定制课程,今年年初我花了一个月整理了一份最适合2019年学习的web前端学习干货,各种框架都有整理,送给每一位前端小伙伴,想要获取的可以关注我并在后台私信我:前端,即可免费获取。

作者:zhangbao90s

链接:https://juejin.im/post/5dbbd439f265da4d4434a976

相等变为1 编号_JavaScript 中的 4 个相等比较算法的介绍相关推荐

  1. 第九十六期:JavaScript 中的 4 个相等比较算法的介绍

    JavaScript 运算中,一共包含 4 个相等比较算法:抽象相等比较:严格相等比较:SameValueZero:SameValue. 作者:zhangbao90s JavaScript 运算中,一 ...

  2. 字符串在编号查询中的应用示例及常见问题.sql

    --1. 构造使用IN子句的动态Transact-SQL方法进行编号查询 --a. 要查询的字段类型是数字型 --查询的值列表 DECLARE @idlist varchar(100) SET @id ...

  3. 将不确定变为确定~Razor视图中是否可以嵌套JS代码

    这个问题有点意思,Razor的自动闭合性,导致JS代码不能直接与Razor代码混排,原来ASPX页面中,我们到处可见这种代码 <%if(Model!=null){foreach (var ite ...

  4. 如何在Word中跳过编号列表中的编号

    A numbered list in Word is simply a series of numbered paragraphs. There may be times when you want ...

  5. js 正则中冒号代表什么_javascript中正则表达式语法详解

    好久都没有写博客了,主要是太懒了,尤其是在阳春三月,风和日丽的日子,太阳暖暖的照在身上,真想美美的睡上一觉.就导致了这篇博客拖到现在才开始动笔,javascript的正则这一块也不是什么新的东西,主要 ...

  6. 自动驾驶中常用的四类机器学习算法

    来源:智车科技 机器学习算法已经被广泛应用于自动驾驶各种解决方案,电控单元中的传感器数据处理大大提高了机器学习的利用率,也有一些潜在的应用,比如利用不同外部和内部的传感器的数据融合(如激光雷达.雷达. ...

  7. 为什么神经元有数千个突触,一个新皮质中的序列记忆理论(HTM算法基础)

    为什么神经元有数千个突触,一个新皮质中的序列记忆理论(HTM算法基础) Jeff Hawkins* and Subutai Ahmad Numenta, Inc., Redwood City, CA, ...

  8. 金融系统中PBOC/EMV的TLV的算法实现(含C++/C#)

    金融系统中PBOC/EMV的TLV的算法实现(含C++/C#) TLV即Tag-Length-Value,常在IC卡与POS终端设备中通过这样的一个应用通信协议进行数据交换.在金融系统以及认证中,PB ...

  9. 计算机科学中最重要的32个算法

    英文原址:http://www.risc.jku.at/people/ckoutsch/stuff/e_algorithms.html 奥地利符号计算研究所(Research Institute fo ...

最新文章

  1. 深度学习领域最常用的10个激活函数,一文详解数学原理及优缺点
  2. python读取文件的常用方法
  3. js修改地址栏url_在gulp、create-react-app中css,js中的文件路径
  4. java f.add()_f.add(p1,First); 那个“First”是什么意思呀?
  5. 设计一个较为合理的实验方案来研究芳纶纤维的染色热力学性能
  6. PHP检测每一段代码执行时间
  7. mysql导出数据大概得多久_MySQL 导出数据
  8. w ndows平板,Win8.1千元芯平板 昂达V975w四核评测
  9. EdrawMax使用方法
  10. redis下载与安装(windows版)
  11. metricbeat的基本使用
  12. pscs6怎么做html模板,ps cs6设计个人作品网页模板教程(6)
  13. Android debug时一直处于waiting for debugger解决办法
  14. 【百度网盘】 个人资源共享
  15. eCharts改变饼图的默认颜色
  16. DataV(对象类)展示8 ~ 20 °C
  17. html懒人素材网,懒人图库 - 矢量图,JS代码,网页素材 - 学会偷懒,懒出境界!
  18. 软考网络工程师怎么学习,用那些书籍?
  19. python1000行代码_写个人脸识别程序员,C可能要两千行代码,Java两百!但是Python只需二十行即可!...
  20. 如何把mkv文件转换成mp4?

热门文章

  1. phpstorm 2019.1 mac
  2. oracle 配置 ACL 使用数据库发送WebServic请求时需要
  3. 基础篇:3.3.2)压铸件-材料选择
  4. centos7下memcached的安装配置
  5. GridView中的全选操作(转)
  6. MFC Radio Button笔记
  7. uniapp---使用浏览器_Android真机_Iphone真机实时展示uniapp_一次开发_小程序_Android_IOS_快应用通用工作笔记003
  8. 微服务架构工作笔记003---了解认识google Kubernetes 容器管理
  9. 测试工作笔记001---web测试_工作经验_注意点_随时更新
  10. SpringCloud工作笔记058---springBoot项目maven命令打包部署