ES6以后有三种判等方法
- 抽象(非严格)相等比较 (
==
) - 严格相等(全等)比较 (
===
) - 同值相等Object.is (ES6新特性)
使用哪一种比较全看你的业务需要,不过一般都用===
和Object.is
MDN中有很详细的介绍,这里直接拿过来用了
在做相同的比较时,三种方法的区别
双等号==
将执行类型转换,
三等号
不进行类型转换(如果类型不同, 只是总会返回 false)
Object.is
基本上与三等号相同,但是对于NaN和-0和+0进行特殊处理
Object.is(NaN,NaN)将为
true
,在==
和===
中将是false
,
严格相等===
全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。如果两个被比较的值具有不同的类型,这两个值是不全等的。否则,如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。
var num = 0;
var obj = new String("0");
var str = "0";
var b = false;
console.log(num === num); // true
console.log(obj === obj); // true
console.log(str === str); // true
console.log(num === obj); // false
console.log(num === str); // false
console.log(obj === str); // false
console.log(null === undefined); // false
console.log(obj === null); // false
console.log(obj === undefined); // false
对不同类型的值,全等操作符有不同的处理
-
非数值:
全等操作符使用明确的语义进行比较:一个值只与自身全等。
-
数值:
全等操作符使用略加修改的语义来处理两个特殊情况
- 浮点数 0 , 是不分正负的,全等操作符认为这两个值是全等的
- 浮点数包含了 NaN 值,全等操作符认为 NaN 与其他任何值都不全等,包括它自己。
非严格相等 ==
最好永远都不要使用相等操作符。全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。
相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-8mxfsfEm-1619059763128)(assets/1619058832799.png)]
console.log(num == num); // true
console.log(obj == obj); // true
console.log(str == str); // true
console.log(num == obj); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true
// 两个都是false,极少数情况会是true
console.log(obj == null);
console.log(obj == undefined);
同值相等Object.is
同值相等(Object.is
)解决了最后一个用例
// 向 Nmuber 构造函数添加一个不可变的属性 NEGATIVE_ZERO
Object.defineProperty(Number, "NEGATIVE_ZERO",
{ value: -0, writable: false, configurable: false, enumerable: false });
function attemptMutation(v)
{
Object.defineProperty(Number, "NEGATIVE_ZERO", { value: v });
}
Object.defineProperty
在试图修改不可变属性时,如果这个属性确实被修改了则会抛出异常,反之什么都不会发生。例如如果 v 是 -0 ,那么没有发生任何变化,所以也不会抛出任何异常。但如果 v 是 +0 ,则会抛出异常。不可变属性和新设定的值使用 同值(same-value) 相等比较。
**什么时候使用Object.is或者三等===**
总的来说,Object.is
和===
,也就在对NaN
的处理才有比较大的不同,如果你不清楚具体的区别,使用===
就行了,避免使用Object.is
。
即使你需要比较两个NaN
使其结果为true
,也可以使用ES6以前的isNan方法。