概述
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 |