JavaScript的相等比較(==)和(===)及Object.is()的區別

比較運算符之相等運算符

ES5 比較兩個值是否相等,只有兩個運算符:相等運算符(==)和嚴格相等運算符(===)。前者在比較時對於不一樣數據類型的值會進行類型轉換;然後者不會轉換,且結果更容易預測,而且由於沒有隱式轉換,全等比較的運行會更快。所以建議使用嚴格相等運算符===進行值的比較。數組

嚴格相等運算符 ===

(1) 不一樣類型的值比較

若是比較的兩個值的類型不一樣,直接返回false。瀏覽器

1 === "1"        // false
true === "true"  // false

(2) 原始類型值比較

原始類型值有五種:undefined、null、布爾值(Boolean)、字符串(String)、數值(Number)。函數

1. 非數值類型比較

值相同就返回true,值不一樣就返回false。spa

null === null        // true
null === undefined   // false
2. 數值類型比較

正常狀況下值相同就返回true,值不一樣就返回false。但有兩個特殊狀況:code

一是0不分正負對象

0 === -0   //true

二是 NaN 自己不全等於任何值。blog

NaN === NaN   //false
NaN !== NaN   //true

也就是說 等式 (x !== x) 成立的惟一狀況是 x 的值爲 NaN。內存

(3) 複合類型值比較

複合類型的值實際上存儲的是數據的內存地址,所以兩個複合類型(對象、數組、函數)的數據比較時,不是比較它們的值是否相等,而是比較它們是否指向同一個地址。字符串

{} === {} // false
[] === [] // false
(function () {} === function () {}) // false

上面代碼分別比較兩個空對象、兩個空數組、兩個空函數,結果都是不相等。那是由於空對象、空數組、空函數的值,都存放在不一樣的內存地址,所以結果是false。部署

而若是兩個變量引用同一個對象,那它們則相等,由於它們引用的對象存儲在同一個內存地址。

var v1 = {};
var v2 = v1;
v1 === v2 // true

相等運算符 ==

相等運算符用來比較相同類型的數據以及複合類型數據時,與嚴格相等運算符徹底同樣。比較不一樣類型的數據時,相等運算符會先將數據進行類型轉換,而後再用嚴格相等運算符比較。

(1) 原始類型值比較

原始類型的值會轉換成數值再進行比較。轉換規則是使用 Number() 轉換。

1 == true // true    // 等同於 1 === Number(true)
0 == false // true  // 等同於 0 === Number(false)
'true' == true // false  // 等同於 Number('true') === Number(true)
'' == 0 // true         // 等同於 Number('') === 0
'' == false  // true  // 等同於 0 === 0
'\n  123  \t' == 123  // true  // 由於字符串轉爲數字時,省略前置和後置的空格

(2) undefined 和 null

undefined 和 null 與其餘類型的值比較時,結果都爲 false,它們互相比較時結果爲 true。

false == null         // false
false == undefined    // false
0 == null            // false
0 == undefined       // false
NaN == undefined     // false
undefined == null    // true

(3) 對象與原始類型值比較

對象(這裏指廣義的對象,包括數組和函數)與原始類型的值比較時,對象轉換成原始類型的值,再進行比較。

1. 對象與數值比較時,對象轉爲數值 Number()
[1] == 1 // true
// 等同於 Number([1]) == 1
2. 對象與字符串比較時,對象轉爲字符串 String()
[1] == '1' // true
// 等同於 String([1]) == '1'
[1, 2] == '1,2' // true
// 等同於 String([1, 2]) == '1,2'
3. 對象與布爾值比較時,兩邊都轉爲數值
[1] == true // true
// 等同於 Number([1]) == Number(true)
[2] == true // false
// 等同於 Number([2]) == Number(true)

Object.is(value1, value2)

相等運算符(==)和嚴格相等運算符(===)都有缺點,前者會自動轉換數據類型,後者的NaN不等於自身,以及+0等於-0。所以 ES6 的新方法Object.is能夠用來解決這個問題。

Object.is 用來比較兩個值是否嚴格相等,與嚴格比較運算符(===)的行爲基本一致。返回布爾值,相等返回 true,不相等返回 false

不一樣之處只有兩個:一是+0不等於-0,二是NaN等於自身。

+0 === -0 //true
NaN === NaN // false

Object.is(+0, -0) // false
Object.is(NaN, NaN) // true

對於不兼容 ES6 的瀏覽器,能夠在ES5 環境下經過下面的代碼,部署Object.is。

Object.defineProperty(Object, 'is', {
  value: function(x, y) {
    if (x === y) {
      // 針對+0 不等於 -0的狀況
      return x !== 0 || 1 / x === 1 / y;
    }
    // 針對NaN的狀況
    return x !== x && y !== y;
  },
  configurable: true,
  enumerable: false,
  writable: true
});

判斷相等一覽表

判斷相等一覽表

相關文章
相關標籤/搜索