JavaScript 中的相等性判断
JavaScript中相等性的判断
截止ES6版本,有四种判断相等的方法:
全等 ===
等于 ==
零值等于 -0 === +0
同值相等 -0 !== +0 (同值相等的底层实现 Object.is()方法)
一、JS中提供有关相等判断的操作方法
1)严格相等 === Strict Equality
2)非严格(抽象/非约束)相等 == Loose(自由的,不受限制的) Equality
3) object.is(v1, v2) ES6新的API, 判断两个参数是否是同一个值
二、=== 严格相等
不进行隐式类型转换。一些情况:
1)要求类型相同,值也相同。
1 === ‘1’? false
1 === 2? false
2)引用值必须是同一地址
var obj = {} obj === obj ? true
{} === {} ? false
3)两个NaN或者是NaN跟其他值都不相等
NaN === NaN ? false
NaN === undefined ? false
4)+0和-0
+0 === -0 ? true
5)Infinity与- Infinity
+Infinity === -Infinity false
三、== 非严格相等
Abstract equality 抽象相等。
隐式类型转换 等式两边都有可能被转换。转换以后还是用严格相等来进行比较。
如果操作数之一是 Boolean,而另一个不是,则将 Boolean 转换为 Number:true 转换为 1,false 转换为 0。然后再次对两个操作数进行宽松比较。
Number 转 String:将 String 转换为 Number。转换失败会得到 NaN,这将确保相等性为 false。
ToPrimitive(A)通过尝试调用A的A.toString()和A.valueOf()方法,将参数A转换为原始值(Primitive)。
Tips:
全等对结果的预测是更加清晰明确
全等在不隐式类型转换的前提下更快
四、使用 Object.is() 进行同值相等比较
同值相等决定了两个值在所有上下文中是否在功能上相同。
4.1、同值相等的比较方法
在同值相等的情况下:
+0 !== -0
NaN === NaN
当尝试更改不可变属性时(如v是+0或者0),Object.defineProperty 会抛出异常,但如果没有请求实际更改,则不会执行任何操作。如果 v 是 -0,则没有请求更改,也不会抛出错误。在内部,重新定义不可变属性时,使用同值相等将新指定的值与当前值进行比较。
4.2、同值相等的实现
同值相等的底层实现 Object.is()
Object.is()是ES6抛出来的方法
ES5并没有暴露JS引擎的同值相等的方法
参数就是两个值,返回值就是同值相等判断的bool结果
Object.is()的判断标准就是同值相等,其不进行隐式类型转换
Object.myIs = function(a, b) {
if (a === b) {
return a !== 0 || 1 / a === 1 / b;
}
return a !== a && b !== b;
}
五、零值相等
类似于同值相等,但 +0 和 -0 被视为相等。
零值相等不作为 JavaScript API 公开,但可以通过自定义代码实现:
function sameValueZero(x, y) {
if (typeof x === "number" && typeof y === "number") {
// x 和 y 相等(可能是 -0 和 0)或它们都是 NaN
return x === y || (x !== x && y !== y);
}
return x === y;
}
零值相等与严格相等的区别在于其将 NaN 视作是相等的,与同值相等的区别在于其将 -0 和 0 视作相等的。