相等性判断

基本概述

四种相等算法

  • 抽象(非严格)相等比较 (==)
  • 严格相等比较 (===): 用于 Array.prototype.indexOf, Array.prototype.lastIndexOf, 和 case-matching
  • 同值零: 用于 %TypedArray%ArrayBuffer 构造函数、以及MapSet操作, 并将用于 ES2016/ES7 中的String.prototype.includes
  • 同值: 用于所有其他地方

三种比较操作

  • 严格相等比较 (也被称作”strict equality”, “identity”, “triple equals”),使用 === ,
  • 抽象相等比较 (“loose equality”,”double equals”) ,使用 ==
  • 以及 Object.is (ECMAScript 2015/ ES6 新特性)

简而言之,在比较两件事情时,双等号将执行类型转换; 三等号将进行相同的比较,而不进行类型转换 (如果类型不同, 只是总会返回 false ); 而Object.is的行为方式与三等号相同,但是对于NaN和-0和+0进行特殊处理,所以最后两个不相同,而Object.is(NaN,NaN)将为 true

严格相等

全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换。

如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等。最后,如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 是不分正负的。区分 +0 和 -0 在解决一些特定的数学问题时是必要的(如除法),但是大部分情况下我们并不用关心。

第二个情况是,浮点数包含了 NaN 值,用来表示某些定义不明确的数学问题的解,例如:正无穷加负无穷。全等操作符认为 NaN 与其他任何值都不全等,包括它自己。

非严格相等

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
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); // true
console.log(num == str); // true
console.log(obj == str); // true
console.log(null == undefined); // true

// both false, except in rare cases
console.log(obj == null);
console.log(obj == undefined);

同值相等

同值相等解决了最后一个用例:确定两个值是否在任何情况下功能上是相同的。

1
2
3
4
5
6
7
8
// 向 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.is 方法提供。

零值相等

与同值相等类似,不过会认为 +0 与 -0 相等。