JavaScript 中的相等性判断
概述
ECMAScript 2015/ES6中有四种相等算法:
- 抽象相等比较(
==
) - 严格相等比较(
===
) Array.prototype.indexOf, Array.prototype.lastIndexOf, 和 case-matching - 同值零: 用于 %TypedArray% 和 ArrayBuffer 构造函数、以及Map和Set操作, 并将用于 ES2016/ES7 中的String.prototype.includes
- 同值: 用于所有其他地方
JavaScript提供三种不同的值比较操作:
- 严格相等 ("triple equals" 或 "identity"),使用 ===
- 宽松相等 ("double equals") ,使用 ==
- 以及 Object.is (ECMAScript 2015/ ES6 新特性)
说明如下:
==
双等号将执行类型转换===
三等号不进行类型转换 (如果类型不同, 直接返回 false )- Object.is的行为方式与三等号相同,但是对于NaN、-0和+0进行特殊处理,所以最后两个不相同,而Object.is(NaN,NaN)将为 true
- 使用双等号或三等号将NaN与NaN进行比较,结果为false
- 对于任意两个不同的非原始对象,即便他们有相同的结构,以上三个运算符都会计算得到 false
严格相等 ===
全等操作符比较两个值是否相等,两个被比较的值在比较前都不进行隐式转换,需要注意:
- 如果两个被比较的值具有不同的类型,这两个值是不全等的
- 如果两个被比较的值类型相同,值也相同,并且都不是 number 类型时,两个值全等
- 如果两个值都是 number 类型,当两个都不是 NaN,并且数值相同,或是两个值分别为 +0 和 -0 时,两个值被认为是全等的
- 全等操作符认为 NaN 与其他任何值都不全等,包括它自己(等式 (x !== x) 成立的唯一情况是 x 的值为 NaN)
- 需要注意两个浮点数比较时的进度缺失问题: 0.1 + 0.2 === 0.3 为false
var num = 0; // Number 原始类型 var obj = new String("0"); // String 对象 var str = "0"; // String 原始类型 var b = false; // Boolean 原始类型 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 console.log(0.1+0.2 === 0.3); //false
非严格相等 ==
相等操作符比较两个值是否相等,在比较前将两个被比较的值转换为相同类型。在转换后(等式的一边或两边都可能被转换),最终的比较方式等同于全等操作符 === 的比较方式。
- 相等操作符满足交换律
- 几乎所有的对象都与 undefined 和 null 不相等
- 大部分浏览器允许 document.all 对象,在某些极端情况下,充当效仿 undefined 的角色,此时和undefined相等
- 当一个对象和原始对象比较时,会尝试调用对象的valueOf()或者toString()方法将对象转换为原始值
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);
Object.is
Object.is 算是JavaScript中同值零比较算法暴露出的一个方法。
Object.is基本和严格相等===
相同,确定两个值是否在任何情况下功能上是相同的。
Object.is认为 +0 和 -0 不相等。
另外一种相等比较算法:同值算法认为 +0 和 -0 相等。
Object.is('foo', 'foo'); // true Object.is(window, window); // true Object.is('foo', 'bar'); // false Object.is([], []); // false var test = { a: 1 }; Object.is(test, test); // true Object.is(null, null); // true // Special Cases Object.is(0, -0); // false Object.is(-0, -0); // true Object.is(NaN, 0/0); // true
判等表
下面列出对于不同类型的比较,==,=== 以及 Object.is 的区别。
x | y | == | === | Object.is |
---|---|---|---|---|
undefined |
undefined |
true |
true |
true |
null |
null |
true |
true |
true |
true |
true |
true |
true |
true |
false |
false |
true |
true |
true |
"foo" |
"foo" |
true |
true |
true |
{ foo: "bar" } |
x |
true |
true |
true |
0 |
0 |
true |
true |
true |
+0 |
-0 |
true |
true |
false |
0 |
false |
true |
false |
false |
"" |
false |
true |
false |
false |
"" |
0 |
true |
false |
false |
"0" |
0 |
true |
false |
false |
"17" |
17 |
true |
false |
false |
[1,2] |
"1,2" |
true |
false |
false |
new String("foo") |
"foo" |
true |
false |
false |
null |
undefined |
true |
false |
false |
null |
false |
false |
false |
false |
undefined |
false |
false |
false |
false |
{ foo: "bar" } |
{ foo: "bar" } |
false |
false |
false |
new String("foo") |
new String("foo") |
false |
false |
false |
0 |
null |
false |
false |
false |
0 |
NaN |
false |
false |
false |
"foo" |
NaN |
false |
false |
false |
NaN |
NaN |
false |
false |
true |