You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Strict Equality Comparison 规定就算 x 和 y 都为 NaN 时,返回的是 false, NaN === NaN 返回的就是 false。但是 SameValueZero 返回的是规定 x 和 y 都为 NaN 时返回的是 true。因此只需要在 Strict Equality Comparison 的基础上处理 NaN 就可以了。
下面这段便是处理 NaN 的:
(value!==value&&other!==other)
在 js 中,只有 NaN 和自身是不相等的,当两个需要比较的值都是和自身不相等时,表明这两个值都为 NaN,返回 true。
本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
gitbook也会同步仓库的更新,gitbook地址:pocket-lodash
本篇分析的是
eq
函数。作用与用法
eq
函数用来比较两个值是否相等。遵循的是 SameValueZero 规范。几个比较规范
SameValueNonNumber
这个规范规定比较的值
x
和y
都不为Number
类型,照抄规范如下:x
的类型不为Number
类型y
的类型与x
的类型一致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
Strict Equality Comparison
js 中的全等(
===
)便是遵循这个规范,照搬规范如下: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
SameValue
规范如下:
x
和y
的类型不同,返回false
x
的类型为Number
x
为NaN
并且y
为NaN
,返回true
x
为+0
并且y
为-0
,返回false
x
为-0
并且y
为+0
, 返回false
x
和y
的数值一致,返回true
false
SameValueZero
这个是
eq
遵循的规范,如下:x
和y
的类型不同,返回false
x
的类型为Number
x
为NaN
并且y
为NaN
,返回true
x
为+0
并且y
为-0
,返回true
x
为-0
并且y
为+0
, 返回true
x
和y
的数值一致,返回true
false
小结:
SameValueNonNumber
是基本,Strict Equality Comparison
、SameValue
和SameValueZero
只是在对待+0
、-0
和NaN
上有区别。源码分析
来看下
eq
的源码:其实
eq
的源码其实就只有这么一句。既然
eq
遵循的是SameValueZero
规范,那就将源码来拆解一下,看它是怎样符合规范的。首先,看第一部分:
就是这么一段,符合的是
Strict Equality Comparison
规范,通过对比可以发现,Strict Equality Comparison
和SameValueZero
只在对待NaN
上有区别。Strict Equality Comparison
规定就算x
和y
都为NaN
时,返回的是false
,NaN === NaN
返回的就是false
。但是SameValueZero
返回的是规定x
和y
都为NaN
时返回的是true
。因此只需要在Strict Equality Comparison
的基础上处理NaN
就可以了。下面这段便是处理
NaN
的:在 js 中,只有
NaN
和自身是不相等的,当两个需要比较的值都是和自身不相等时,表明这两个值都为NaN
,返回true
。这样便遵循了
SameValueZero
的比较实现。可以用Object.is()吗?
Object.is(NaN, NaN)
返回的是true
,所以eq
同样可以改成:Object.is
同样是比较两个值是否一样,但是Object.is(+0, -0)
返回的是false
, 它遵循是的SameValue
规范,因此不可以直接用Object.is
替代eq
。可以用isNaN()吗?
还有个
isNaN
的全局方法,可以用来判断一个值是否为NaN
。例如isNaN(NaN)
会返回true
,那eq
是否可以改成以下形式呢?答案是:不可以!
isNaN
有一个很怪异的行为,如果传入的参数不为Number
类型,会尝试转换成Number
类型之后再做是否为NaN
的判断。所以类似isNaN('notNaN')
返回的也是true
,因为字符串notNaN
会先被转换成NaN
再做判断,这不是我们想要的结果。可以用Number.isNaN()吗
为了修复
isNaN
的缺陷,es6
在Number
对象上扩展了isNaN
方法,只有是NaN
时才会返回true
,因此用Number.isNaN
来判断是安全的。所以eq
同样可以改成以下形式:参考
License
署名-非商业性使用-禁止演绎 4.0 国际 (CC BY-NC-ND 4.0)
最后,所有文章都会同步发送到微信公众号上,欢迎关注,欢迎提意见:
作者:对角另一面
The text was updated successfully, but these errors were encountered: