# eq
# Description
执行 SameValueZero (opens new window) 比较两者的值,来确定它们是否相等
# Params
(value, other)
value : 要比较的值
other : 另一个要比较的值
# Return
Boolean
# Code
function eq(value, other) {
return value === other || (value !== value && other !== other)
}
# Analyze
- 整个
eq方法就只有一行代码,执行 SameValueZero (opens new window) 规范 - 首先
value === other, 符合 Strict Equality Comparison (opens new window) 规范 - Strict Equality Comparison 和 SameValueZero 两者只有在
NaN的处理上有不同,所以就有了value !== value && other !== other - 在
JavaScript中 只有NaN和自身是不相等的,所以 在这里 如果传入的是NaN, 则返回true
# Remark
- 关于JavaScript中的一些对比规范
- 使用 其他方法 也可以判断两个值是否相等,
Object.is() (opens new window) 方法判断两个值是否为同一个值。如果满足以下条件则两个值相等:
- 都是
undefined - 都是
null - 都是
true或false - 都是相同长度的字符串且相同字符按相同顺序排列
- 都是相同对象(意味着每个对象有同一个引用)
- 都是数字且
- 都是
+0 - 都是
-0 - 都是
NaN - 或都是非零而且非
NaN且为同一个值
- 都是
与 == 运算不同。 == 运算符在判断相等前对两边的变量 (如果它们不是同一类型) 进行强制转换 (这种行为的结果会将 "" == false 判断为 true), 而 Object.is 不会强制转换两边的值。
与 === 运算也不相同。 === 运算符 (也包括 == 运算符) 将数字 -0 和 +0 视为相等 ,而将 Number.NaN 与 NaN视为不相等.
SameValueZero 对于 +0 和 -0 返回的是 true,而 Object.is 对于 +0 和 -0 返回的是 false,所以 eq 不能直接用 Object.is 代替, 可改成如下
function eq(value, other) {
return value === other || Object.is(value, other)
}
isNaN() (opens new window) 来检测是否为 NaN 也是不可用的,因为
如果 isNaN 函数的参数不是 Number 类型, isNaN 函数会首先尝试将这个参数转换为数值,然后才会对转换后的结果是否是 NaN 进行判断。因此,对于能被强制转换为有效的非 NaN 数值来说(空字符串和布尔值分别会被强制转换为数值 0 和 1),返回 false 值也许会让人感觉莫名其妙。比如说,空字符串就明显 “不是数值(not a number)”。这种怪异行为起源于:"不是数值(not a number)" 在基于 IEEE-754 数值的浮点计算体制中代表了一种特定的含义。isNaN 函数其实等同于回答了这样一个问题:被测试的值在被强制转换成数值时会不会返回 IEEE-754中所谓的 “不是数值(not a number)”
使用 Number.isNaN() (opens new window) 可以来判断是否 为 NaN
和全局函数 isNaN() 相比,Number.isNaN() 不会自行将参数转换成数字,只有在参数是值为 NaN 的数字时,才会返回 true。
因此 eq 也可以写成如下
function eq(value, other) {
return value === other || (Number.isNaN(value) && Number.isNaN(other))
}
# Example
const object = { 'a': 1 }
const other = { 'a': 1 }
eq(object, object) // => true
eq(object, other) // => false
eq('a', 'a') // => true
eq('a', Object('a')) // => false
eq(NaN, NaN) // => true