JS中的相等性判斷===, ==, Object.is()

首發地址:http://www.geeee.top/2019/11/15/equality-comparisons/,轉載請註明出處數組

相信剛接觸JS的人都會被他的想等性判斷給整糊塗,看看下面代碼,你能答對幾個?函數

NaN === NaN // false
NaN == NaN // false
Object.is(NaN, NaN) // true
0 == false  // true
1 == true   // true
Number(null) === 0  // true
null == 0   // false

Javascript提供了三種不一樣的值比較操做,分別是嚴格相等、寬鬆相等、以及Object.is,但願下面的內容可以對你們有所幫助。code

1. 嚴格相等 x === y判斷邏輯

  1. 若是x的數據類型和y的數據類型不相同,返回false;
  2. 若是x是Number類型
    • x是NaN,返回false
    • y是NaN,返回false
    • x的值和y的值相等,返回true
    • x是+0,y是-0,返回true
    • x是-0,y是+0,返回true
    • 不然返回false
  3. 其餘類型參照SameValueNonNumber(x, y)
    • 斷言:x,y不是Number類型;
    • 斷言: x,y的數據類型相同;
    • x是undefined, y是undefined return true;
    • x是null, y是null,return true;
    • x是字符串類型,當且僅當x,y字符序列徹底相同時(長度相同,每一個位置上的字符也相同)返回true, 不然返回false;
    • 若是x是布爾類型,當x,y都爲true或者都爲false時返回true,不然返回false;
    • 若是x是symbol類型,當x,y是相同的symbol值,返回true,不然返回false;
    • 若是x,y是同一個對象值,返回true,不然返回false;
NaN === NaN // false
undefined === undefined // true
null === null   // true
undefined === null  // false

2. 寬鬆相等 x == y

  1. 若是x,y的類型相同,返回x===y的結果;
  2. 若是x是null, y是undefined, 返回true;
  3. 若是x是undefined, y是null, 返回true;
  4. 若是x是數值,y是字符串, 返回x == ToNumber(y);
  5. 若是x是字符串,y是數值, 返回ToNumber(x) == y;
  6. 若是x是布爾類型, 返回ToNumber(x)==y 的結果;
  7. 若是y是布爾類型,返回 x==ToNumber(y) 的結果;
  8. 若是x是String或Number或Symbol中的一種而且Type(y)是Object,返回 x==ToPrimitive(y) 的結果
  9. 若是Type(x)是Object而且Type(y)是String或Number或Symbol中的一種,返回 ToPrimitive(x)==y 的結果
  10. 其餘返回false
12 == '0xc' // true, 0xc是16進制
12 == '12'  // true
12 == '12c' // false, 說明ToNumber轉換是用的Number()方法

注意對象

Number(null) === 0
可是
null == 0 // false,

image

2.1 ToNumber將一個值轉換爲數值類型

詳情參考數值類型轉換blog

  1. 若是是boolean類型, true返回1,false返回0;
  2. 若是是數值,只是簡單的傳入返回;
  3. 若是是null,返回0
  4. 若是是undefined, 返回NaN;
  5. 若是是字符串,字符串若是隻包含數字,則將其轉換成十進制數;若是是有效的浮點格式,將其轉換成對應的浮點數值;若是是二進制或十六進制將其轉換成對應的十進制數值;
  6. 若是是對象,調用對象的valueOf()方法,而後依照前面規則轉換,若是valueOf返回值是NaN,則調用toString()方法,再依照前面的規則轉換返回的字符串

2.2 ToPrimitive

toPrimitive(A)經過嘗試調用 A 的A.toString() 和 A.valueOf() 方法,將參數 A 轉換爲原始值(Primitive);
JS中原始類型有:Number、String、Boolean、Null、Undefined;ip

不一樣類型對象的valueOf()方法的返回值:字符串

對象 返回值
Array 返回數組對象自己。
Boolean 布爾值
Date 存儲的時間是從 1970 年 1 月 1 日午夜開始計的毫秒數 UTC
Function 函數自己
Number 數字值
Object 對象自己。這是默認狀況, 能夠覆蓋自定義對象的valueOf方法
String 字符串值
// Array:返回數組對象自己
var array = ["ABC", true, 12, -5];
console.log(array.valueOf() === array);   // true

// Date:當前時間距1970年1月1日午夜的毫秒數
var date = new Date(2013, 7, 18, 23, 11, 59, 230);
console.log(date.valueOf());   // 1376838719230

// Number:返回數字值
var num =  15.26540;
console.log(num.valueOf());   // 15.2654

// 布爾:返回布爾值true或false
var bool = true;
console.log(bool.valueOf() === bool);   // true

// new一個Boolean對象
var newBool = new Boolean(true);
// valueOf()返回的是true,二者的值相等
console.log(newBool.valueOf() == newBool);   // true
// 可是不全等,二者類型不相等,前者是boolean類型,後者是object類型
console.log(newBool.valueOf() === newBool);   // false

// Function:返回函數自己
function foo(){}
console.log( foo.valueOf() === foo );   // true
var foo2 =  new Function("x", "y", "return x + y;");
console.log( foo2.valueOf() );
/*
ƒ anonymous(x,y
) {
return x + y;
}
*/

// Object:返回對象自己
var obj = {name: "張三", age: 18};
console.log( obj.valueOf() === obj );   // true

// String:返回字符串值
var str = "http://www.xyz.com";
console.log( str.valueOf() === str );   // true

// new一個字符串對象
var str2 = new String("http://www.xyz.com");
// 二者的值相等,但不全等,由於類型不一樣,前者爲string類型,後者爲object類型
console.log( str2.valueOf() === str2 );   // false

3.同值相等

同值相等由 Object.is 方法判斷:get

  • 兩個值都是 undefined
  • 兩個值都是 null
  • 兩個值都是 true 或者都是 false
  • 兩個值是由相同個數的字符按照相同的順序組成的字符串
  • 兩個值指向同一個對象
  • 兩個值都是數字而且
    • 都是正零 +0,
    • 或者都是負零 -0,
    • 或者都是 NaN
    • 都是除零和 NaN 外的其它同一個數字
Object.is('foo', 'foo');     // true
Object.is(window, window);   // true

Object.is('foo', 'bar');     // false
Object.is([], []);           // false

var foo = { a: 1 };
var bar = { a: 1 };
Object.is(foo, foo);         // true
Object.is(foo, bar);         // false

Object.is(null, null);       // true

Object.is(true, 'true')     // false

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

4.零值相等

與同值相等相似,不過會認爲 +0 與 -0 相等。string

小結

  • === 不作類型轉換,當兩邊的數類型不相同時,直接返回false;當前類型相同且都是數值類型的時候,有一個是NaN,那麼結果就是false, 另外 +0 === -0
  • ==運算符,當兩邊操做數類不相同時會作隱式轉換,而後才進行比較,這樣的話就會出現 false == 0, '' == false 等現象, 可是Object.is不會作這種轉換
相關文章
相關標籤/搜索