JS中相等判断,三等号===、双等号==、同值Object.is的区别详解

532 阅读3分钟

ES6以后有三种判等方法

  • 抽象(非严格)相等比较 (==)
  • 严格相等(全等)比较 (===)
  • 同值相等Object.is (ES6新特性)

使用哪一种比较全看你的业务需要,不过一般都用===Object.is

MDN中有很详细的介绍,这里直接拿过来用了

在做相同的比较时,三种方法的区别

  1. 双等号==
    将执行类型转换,
  2. 三等号
    不进行类型转换(如果类型不同, 只是总会返回 false)
  3. 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 与其他任何值都不全等,包括它自己

非严格相等 ==

最好永远都不要使用相等操作符。全等操作符的结果更容易预测,并且因为没有隐式转换,全等比较的操作会更快。

相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。

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方法。