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 与其他任何值都不全等,包括它自己。
非严格相等 ==
最好永远都不要使用相等操作符。全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。
相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。
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方法。