lodash源码中,如何将NaN不是NaN表述为?
摘要:暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面。 ——梁文道《暗恋到偷窥》 本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star: "pocket lodash&a
暗恋之纯粹,在于不求结果,完全把自己锁闭在一个单向的关系里面。
——梁文道《暗恋到偷窥》
本文为读 lodash 源码的第五篇,后续文章会更新到这个仓库中,欢迎 star:pocket-lodash
gitbook也会同步仓库的更新,gitbook地址:pocket-lodash
本篇分析的是 eq 函数。
作用与用法
eq 函数用来比较两个值是否相等。遵循的是 SameValueZero 规范。
var obj1 = {test: 1}
var obj2 = {test: 1}
var obj3 = obj1
_.eq(1,1) // true
_.eq(+0, -0) // true
_.eq(obj1, obj3) // true
_.eq(obj1, obj2) // false
_.eq(NaN, NaN) // false
几个比较规范
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 类型:
a. 如果 x 为 NaN ,返回 false
b. 如果 y 为 NaN ,返回 false
c. 如果 x 和 y 的数值一致,返回 true
d. 如果 x 为 +0 并且 y 为 -0 ,返回 true
e. 如果 x 为 -0 并且 y 为 +0 ,返回 true
f. 返回 false
按照 SameValueNonNumber 的结果返回
SameValue
规范如下:
如果 x 和 y 的类型不同,返回 false
如果 x 的类型为 Number
a. 如果 x 为 NaN 并且 y 为 NaN ,返回 true
b. 如果 x 为 +0 并且 y 为 -0 ,返回 false
c. 如果 x 为 -0 并且 y 为 +0 , 返回 false
d. 如果 x 和 y 的数值一致,返回 true
e. 返回 false
按照 SameValueNonNumber 的结果返回
SameValueZero
这个是 eq 遵循的规范,如下:
如果 x 和 y 的类型不同,返回 false
如果 x 的类型为 Number
a. 如果 x 为 NaN 并且 y 为 NaN ,返回 true
b. 如果 x 为 +0 并且 y 为 -0 ,返回 true
c. 如果 x 为 -0 并且 y 为 +0 , 返回 true
d. 如果 x 和 y 的数值一致,返回 true
e. 返回 false
按照 SameValueNonNumber 的结果返回
小结:SameValueNonNumber 是基本,Strict Equality Comparison 、SameValue 和 SameValueZero 只是在对待 +0、-0 和 NaN 上有区别。
源码分析
来看下 eq 的源码:
function eq(value, other) {
return value === other || (value !== value && other !== other)
}
其实eq 的源码其实就只有这么一句。
既然 eq 遵循的是 SameValueZero 规范,那就将源码来拆解一下,看它是怎样符合规范的。
首先,看第一部分:
value === other
就是这么一段,符合的是 Strict Equality Comparison 规范,通过对比可以发现, Strict Equality Comparison 和 SameValueZero 只在对待 NaN 上有区别。
