摘要:还规定了无穷及其它的相应规范,有兴趣可自行查找相关资料。其它相同数值相等。类型中,引用同一对象,相等。不同点对的判断上各有不同。以为代表的相等和相等以为代表的不相等和相等以为代表的相等和不相等相同类型采用严格比较。
相等不相等?
先来随便举几个?吧~
"0" == true //? [1] == [1] //? [1] == 1 //? null == false //? null == undefined //? NaN === NaN //? +0 === -0 //? Object.is([], []) //? Object.is(-0, +0) //? Object.is(NaN, NaN) //? var arr = [NaN, 0, +0] arr.indexOf(-0) //? arr.indexOf(NaN) //? arr.includes(-0) //? arr.includes(NaN) //?
可能 ±0、NaN 会纠结一点,还是比较基础的,也许很多人一眼扫过去便知道答案了,网上也已经有了很多相关的经验总结。我在这里结合官方规范进行了整理,希望能带给你不一样的认识。
预备知识 ECMAScript Language Types传送门。根据最新规范,EcmaScript 一共有7种语言类型:
Undefined
Null
Number
String
Boolean
Symbol
Object
我们经常把 Object 类型称为 引用数据类型,其它5种则为基本数据类型。(Symbol怎么说..?
ToNumber传送门。任意 EcmaScript 类型转化为 Number 类型:
类型 | 结果 | |
---|---|---|
Undefined | NaN | |
Null | +0 | |
Boolean | true -> 1,false -> +0 | |
Number | 不转变 | |
String | 空字符串 -> +0,有效的数字 -> 十进制数字,其它 -> NaN | |
Object | 先ToPrimitive(hint Number),再ToNumber | |
Symbol | 抛错,TypeError 错误 |
传送门。内部方法,主要功能是将引用数据类型转化为基本数据类型。
根据内部标记 hint 的不同有不同的调用顺序。
hint有三种:default、number、string。default 默认遵照 number 规则。
default/number:先 valueOf,后 toString。一般转化规则皆如此。
string:先 toString,后 valueOf。如Date对象方法、String()转化等。
如果 toString/valueOf 中某一方法返回类型不为对象类型,则直接返回该值,不会继续调用后面方法。如果两者都返回对象类型,会抛 TypeError 错误。
-0、+0、0 的疑惑明明日常没什么卵用,为什么会有±0?
其实遵从IEEE754标准的编程语言都有±0的概念,IEEE754标准的64位浮点数,是以1+11+53形式的符号位+阶数位+尾数位表示。
符号位、阶数位、尾数位都是0,那便是+0,也就是常规的数字0。
符号位为1,阶数位、尾数位都是0,那便是 -0。
IEEE754还规定了NaN、无穷及其它的相应规范,有兴趣可自行查找相关资料。
PS这部分其实是后加的,你会发现每个知识点都是紧密相连的,构成了一个庞大的知识网络,限于篇幅我不会详细介绍,但我会尽量贴出规范出处,大家可自行研究。
SameValueNonNumber 内部方法SameValueNonNumber 方法接收两个参数 x 和 y ,其中 x 和 y 都不是 Number 类型,该方法返回 true 或 false。
主要规则断言:x 不是 Number 类型。
断言:x 和 y 是 相同类型。
如果 x 是 Undefined 类型,返回 true 。
如果 x 是 Null 类型,返回 true 。
如果 x 是 String 类型:
如果 x 和 y 长度相同且相应编码单元相同,返回 true 。
否则返回 false 。
如果 x 是 Boolean 类型:
如果 x 和 y 都是true 或者 都是false,返回 true 。
否则返回 false 。
如果 x 是 Symbol 类型:
如果 x 和 y 都是相同 Symbol 值,返回 true 。
否则返回 false 。
如果 x 和 y 指向同一对象,返回 true 。否则返回 false 。
小结相同类型比较规则(除Number类型)
都是 undefined,相等。
都是 null,相等。
String 类型中,都是相同字符串,相等。
Boolean 类型中,都是 true 或者 都是 false,相等。
Symbol 类型中,都是相同 Symbol 值,相等。
Object 类型中,引用同一对象,相等。
使用哪些 JavaScript 公开方法采用了 SameValueNonNumber 比较呢?
公开方法木有
接着看下去你就会知道,撇开数值类型比较,SameValueNonNumber 是 SameValue、SameValueZero、 === 的公共方法。
SameValueZero 内部方法SameValueZero 方法接收两个参数 x 和 y ,其中 x 和 y 是 EcmaScript 任意类型值,该方法返回 true 或 false。
主要规则如果 x 和 y 的类型不同,返回 false 。
如果 x 是 Number 类型:
如果 x 和 y 都是 NaN ,返回 true 。
如果 x 是 -0 ,y 是 +0 ,返回 true 。
如果 x 是 +0 ,y 是 -0 ,返回 true 。
如果 x 和 y 数值相等,返回 true 。
返回 false 。
返回 SameValueNonNumber(x, y) 方法的返回值。
小结不同类型不相等。
Number 类型中:±0 相等。NaN 和 NaN 相等。其它相同数值相等。
SameValueNonNumber 比较:
都是 undefined,相等。
都是 null,相等。
String 类型中,都是相同字符串,相等。
Boolean 类型中,都是 true 或者 都是 false,相等。
Symbol 类型中,都是相同 Symbol 值,相等。
Object 类型中,引用同一对象,相等。
使用哪些 JavaScript 公开方法采用了 SameValueZero 比较呢?
Array.prototype.includes
Map.prototype.delete
Map.prototype.has
Map.prototype.set
Set.prototype.delete
Set.prototype.has
Set.prototype.add
ArrayBuffer 和 DataView 部分方法
SameValue 内部方法SameValue 方法接收两个参数 x 和 y ,其中 x 和 y 是 EcmaScript 中任意类型值,该方法返回 true 或 false。
主要规则如果 x 和 y 的类型不同,返回 false 。
如果 x 是 Number 类型:
如果 x 和 y 都是 NaN ,返回 true 。
如果 x 是 -0 ,y 是 +0 ,返回 false 。
如果 x 是 +0 ,y 是 -0 ,返回 false 。
如果 x 和 y 数值相等,返回 true 。
返回 false 。
返回 SameValueNonNumber(x, y) 方法的返回值。
小结不同类型不相等。
Number 类型中:±0 不相等。NaN 和 NaN 相等。其它相同数值相等。
SameValueNonNumber 比较:
都是 undefined,相等。
都是 null,相等。
String 类型中,都是相同字符串,相等。
Boolean 类型中,都是 true 或者 都是 false,相等。
Symbol 类型中,都是相同 Symbol 值,相等。
Object 类型中,引用同一对象,相等。
使用哪些 JavaScript 公开方法采用了 SameValue 比较呢?
Object.is
在最新的 ES 规范 中,你会发现许多其它内部方法和公开方法都应用了 SameValue 比较方法,其中大部分也没有涉及数值比较。
至于为什么是 SameValue 方法,而不是 SameValueZero或===。其实我也不知道。。。我个人倾向于认为:SameValue 方法原本在 ES5 规范中便存在了,最新的规范是为了保持规范一致而继续沿用。
=== 严格相等运算Strict Equality Comparison,x === y,返回 true 或者 false。
主要规则如果 x 和 y 的类型不同,返回 false 。
如果 x 是 Number 类型:
如果 x 是 NaN ,返回 false 。
如果 y 是 NaN ,返回 false 。
如果 x 和 y 数值相等,返回 true 。
如果 x 是 -0 ,y 是 +0 ,返回 true 。
如果 x 是 +0 ,y 是 -0 ,返回 true 。
返回 false 。
返回 SameValueNonNumber(x, y) 方法的返回值。
小结不同类型不相等。
Number 类型中:±0 相等。NaN 和 NaN 不相等。其它相同数值相等。
SameValueNonNumber比较:
都是 undefined,相等。
都是 null,相等。
String 类型中,都是相同字符串,相等。
Boolean 类型中,都是 true 或者 都是 false,相等。
Symbol 类型中,都是相同 Symbol 值,相等。
Object 类型中,引用同一对象,相等。
使用哪些 JavaScript 公开方法采用了 === 比较呢?
=== 严格相等运算
左右两边是相同类型的 == 相等运算
switch语句中的case
Array.prototype.indexOf
Array.prototype.lastIndexOf
== 相等运算Abstract Equality Comparison,x == y,返回 true 或者 false。
主要规则
如果 x 和 y 的类型相同:
返回严格相等运算结果 x === y 。
如果 x 是 null ,y 是 undefined ,返回 true 。
如果 x 是 undefined ,y 是 null ,返回 true 。
如果 x 是 Number 类型 ,y 是 String 类型,返回 x == ToNumber(y) 运算结果。
如果 x 是 String 类型 ,y 是 Number 类型,返回 ToNumber(x) == y 运算结果。
如果 x 是 Boolean 类型 ,返回 ToNumber(x) == y 运算结果。
如果 y 是 Boolean 类型 ,返回 x == ToNumber(y) 运算结果。
如果 x 是 Number、String、Symbol 中任意一个类型 ,y 是 Object 类型,返回 x == ToPrimitive(y) 运算结果。
如果 y 是 Number、String、Symbol 中任意一个类型 ,x 是 Object 类型,返回 ToPrimitive(x) == y 运算结果。
返回 false 。
小结相同类型:遵循 === 严格相等比较规则。
null == undefined,相等。
不同类型:
基本数据类型转换为 Number 类型再 == 比较。
引用数据类型执行内部 ToPrimitive方法后再 == 比较。
使用哪些 JavaScript 公开方法采用了 == 比较呢?
只有这只 == 相等运算
相等不相等开头的答案。如果对结果感到好奇,不妨对着上面的过程比对~
"0" == true // false [1] == [1] // false [1] == 1 // true null == false // false null == undefined // true NaN === NaN // false +0 === -0 // true Object.is([], []) // false Object.is(-0, +0) // false。见SameValue Object.is(NaN, NaN) // true。见SameValue var arr = [NaN, 0, +0] arr.indexOf(-0) // 1。见=== arr.indexOf(NaN) // -1。见=== arr.includes(-0) // true。见SameValueZero arr.includes(NaN) // true。见SameValueZero总结
SameValueZero、SameValue、===这仨完全差不多嘛!
相同点:
- 不同类型即不相等。 - 相同类型遵从`SameValueNonNumber`规则。
不同点:对±0、NaN 的判断上各有不同。
以 Array.prototype.includes 为代表的SameValueZero
±0 相等
NaN 和 NaN 相等
以 Object.is 为代表的SameValue
±0 不相等
NaN 和 NaN 相等
以 ===、Array.prototype.indexOf 为代表的===
±0 相等
NaN 和 NaN 不相等
==
相同类型采用===严格比较。
不同类型会隐式转换:
基本数据类型转换为 Number 类型再 == 比较。
引用数据类型执行 ToPrimitive 转换后再 == 比较。
undefined/null 特例。
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/92237.html
摘要:前端渲染过程的二三事本文不会介绍整个前端渲染过程的步骤,只是记录最近阅读的文章的些许思考和感悟。那么现在我们可以明白这个问题的关键所在了,因为在大部分页面中是拥有的,而由于其解析顺序,那么在事件之前必定已经成功构造树。 前端渲染过程的二三事 本文不会介绍整个前端渲染过程的步骤,只是记录最近阅读的文章的些许思考和感悟。(文章地址一(系列),文章地址二) 希望大家在阅读这篇文章之前能将上述...
摘要:但对于整个事件流上的别的元素来说,执行顺序还会受到另外一个因素的影响。以上面的场景为例,在捕获阶段执行的事件,如果执行,则事件流终止,不会到达目标阶段,的世界则不会被执行执行结果为线上参考事件流 向dom绑定事件的事件的三种方式 行内绑定 按钮 js内绑定 btnDom.onclick = function clickHandler() { console.log(click)...
摘要:分表字段的选择。问题产生之前提到在分表应用上线前我们需要将原有表的数据迁移到新表中,这样才能保证业务不受影响。虽说凌晨的业务量下降,但依然有少部分的请求过来,也会出现各种数据库异常。 showImg(https://segmentfault.com/img/remote/1460000019462791?w=496&h=285); 前言 本篇是上一篇《一次分表踩坑实践的探讨》,所以还没...
阅读 1904·2021-11-25 09:43
阅读 1404·2021-11-22 14:56
阅读 3279·2021-11-22 09:34
阅读 2009·2021-11-15 11:37
阅读 2255·2021-09-01 10:46
阅读 1395·2019-08-30 15:44
阅读 2293·2019-08-30 13:15
阅读 2392·2019-08-29 13:07