console.log(null == false);
開門見山,說出你的答案!
對,沒錯,答案是
false
!
讓我們一探究竟吧!
規定
先來閱讀以下兩份規則:
- JavaScript 中的相等性判斷
- 讀懂 ECMAScript 規格
嚴格相等 === :
全等操作符比較兩個值是否相等,兩個被比較的值在比較前都不進行隐式轉換。如果兩個被比較的值具有不同的類型,這兩個值是不全等的。否則,如果兩個被比較的值類型相同,值也相同,并且都不是 number 類型時,兩個值全等。最後,如果兩個值都是 number 類型,當兩個都不是 NaN,并且數值相同,或是兩個值分别為 +0 和 -0 時,兩個值被認為是全等的。
var num = ;
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
相等運算== :
The comparison x == y, where x and y are values, produces true or false.
- 如果x不是正常值(比如抛出一個錯誤),中斷執行。
- 如果y不是正常值,中斷執行。
- 如果Type(x)與Type(y)相同,執行嚴格相等運算x === y。
- 如果x是null,y是undefined,傳回true。
- 如果x是undefined,y是null,傳回true。
- 如果Type(x)是數值,Type(y)是字元串,傳回x == ToNumber(y)的結果。
- 如果Type(x)是字元串,Type(y)是數值,傳回ToNumber(x) == y的結果。
- 如果Type(x)是布爾值,傳回ToNumber(x) == y的結果。
- 如果Type(y)是布爾值,傳回x == ToNumber(y)的結果。
- 如果Type(x)是字元串或數值或Symbol值,Type(y)是對象,傳回x == ToPrimitive(y)的結果。
- 如果Type(x)是對象,Type(y)是字元串或數值或Symbol值,傳回ToPrimitive(x) == y的結果。
- return false。
那麼我們提煉以下規則:
- 如果 x或者y不是正常值,中斷執行。
- 如果 typeof x 和typeof y相同,執行x === y。
- 如果 x和y分别是null和undefined,傳回true。
- 如果 x和y分别是數值和字元串類型,那麼傳回 x == Number(y) (y 為字元串)
- 如果 x和y其中一個為布爾類型,那麼傳回x == Number(y) (若 x 為布爾類型)
- 如果 x和y分别是(Symbol值 或 數值 或 字元串) 和 對象,傳回x == ToPrimitive(y) (若 y 為對象)
- return false
1、将值轉為原始值,ToPrimitive()。
2、将值轉為數字,ToNumber()。
3、将值轉為字元串,ToString()。
1.ToPrimitive()
js引擎内部的抽象操作ToPrimitive有着這樣的簽名:
ToPrimitive(input, PreferredType?)
input是要轉換的值,PreferredType是可選參數,可以是Number或String類型。他隻是一個轉換标志,轉化後的結果并不一定是這個參數所值的類型,但是轉換結果一定是一個原始值(或者報錯)。
1.1如果PreferredType被标記為Number,則會進行下面的操作流程來轉換輸入的值。
1、如果輸入的值已經是一個原始值,則直接傳回它
2、否則,如果輸入的值是一個對象,則調用該對象的valueOf()方法,
如果valueOf()方法的傳回值是一個原始值,則傳回這個原始值。
3、否則,調用這個對象的toString()方法,如果toString()方法傳回的是一個原始值,則傳回這個原始值。
4、否則,抛出TypeError異常。
1.2如果PreferredType被标記為String,則會進行下面的操作流程來轉換輸入的值。
1、如果輸入的值已經是一個原始值,則直接傳回它
2、否則,調用這個對象的toString()方法,如果toString()方法傳回的是一個原始值,則傳回這個原始值。
3、否則,如果輸入的值是一個對象,則調用該對象的valueOf()方法,
如果valueOf()方法的傳回值是一個原始值,則傳回這個原始值。
4、否則,抛出TypeError異常。
既然PreferredType是可選參數,那麼如果沒有這個參數時,怎麼轉換呢?PreferredType的值會按照這樣的規則來自動設定:
、該對象為Date類型,則PreferredType被設定為String
、否則,PreferredType被設定為Number
toString()
和
valueOf()
的用法有待補充。
2.ToNumber()
根據參數類型進行下面轉換:
參數 | 結果 |
---|---|
undefined | NaN |
null | +0 |
布爾值 | true轉換1,false轉換為+0 |
數字 | 無須轉換 |
字元串 | 有字元串解析為數字,例如:‘324’轉換為324,‘qwer’轉換為NaN |
對象 | 先進行 ToPrimitive(obj, Number)轉換得到原始值,在進行ToNumber轉換為數字 |
3.ToString()
根據參數類型進行下面轉換:
參數 | 結果 |
---|---|
undefined | ‘undefined’ |
null | ‘null’ |
布爾值 | 轉換為’true’ 或 ‘false’ |
數字 | 數字轉換字元串,比如:1.765轉為’1.765’ |
字元串 | 無須轉換 |
對象 | 先進行 ToPrimitive(obj, String)轉換得到原始值,在進行ToString轉換為字元串 |
Object.is():
Object.is()
判斷兩個值是否相同。如果下列任何一項成立,則兩個值相同:
- 兩個值都是 undefined
- 兩個值都是 null
- 兩個值都是 true 或者都是 false
- 兩個值是由相同個數的字元按照相同的順序組成的字元串
- 兩個值指向同一個對象
- 兩個值都是數字并且
- 都是正零 +0
- 都是負零 -0
- 都是 NaN
- 都是除零和 NaN 外的其它同一個數字
這種相等性判斷邏輯和傳統的
==
運算符所用的不同,
==
運算符會對它兩邊的操作數做隐式類型轉換(如果它們類型不同),然後才進行相等性比較,(是以才會有類似
"" == false
為
true
的現象),但
Object.is
不會做這種類型轉換。
這與
===
運算符也不一樣。
===
運算符(和
==
運算符)将數字值
-0
和
+0
視為相等,并認為
Number.NaN
不等于
NaN
。
示例:
Object.is('foo', 'foo'); // true
Object.is(window, window); // true
Object.is('foo', 'bar'); // false
Object.is([], []); // false
var test = { a: };
Object.is(test, test); // true
Object.is(null, null); // true
// 特例
Object.is(, -); // false
Object.is(-, -); // true
Object.is(NaN, /); // true
實際運用
我們先看以下以下幾種值比較的結果:
挑選重點來分析如下:
①
左邊數組類型為
Obeject
,右邊是
String
,滿足總結條件6。
執行
ToPrimitive([1,2])
,在沒有參數的情況下且不為
Date
類型,轉換類型自動為
Number
再執行
[1,2].valueOf()
,類型還是
Obeject
,不為原始值
再執行
[1,2].toString()
,
"1,2"
為字元串原始值
最後比較
"1,2" == "1,2"
,傳回
true
②
開始的那個問題:
因為
false
是Boolean類型,滿足總結中的第五條,是以實際比較
Number(bull) == false;
== null;
//false
最新的 ECMAScript 标準定義了 7 種資料類型:
6 種 原始類型:
Boolean
Null
Undefined
Number
String
Symbol (ECMAScript 6 新定義)
和 Object
0 == null
null的類型是
Null
,實際上這個比較不滿足轉換的任何一條規則,是以傳回
false
。
③
兩邊都是
Number
類型,是以比較全等
===
傳回false
從數值的角度上講
NaN
不與任何值相等。