可能大家平時大多使用(===),儘量避免了(==),但是在進行(>)和(<)的時候也會發生(==)同樣的隱式轉換,所以這個知識點是必須掌握的。
左值(x) | 右值(y) | 隱式處理 |
---|---|---|
Number | String | ToNumber(y) |
String | Number | ToNumber(x) |
Boolean | others | ToNumber(x) |
others | Boolean | ToNumber(y) |
Object | !Object | Toprimitive(x) |
!Object | Object | Toprimitive(y) |
注意:此處的others表示其它基礎型別
Toprimitive(Object)
先返回valueOf()的值,若返回的不是基礎型別的值,
則返回toString()的值,若返回的不是基礎型別的值,
則丟擲異常。
比較特殊的知識點
Number("[空值或空值的組合]")===0 //true
複製程式碼
什麼是空值?
- null
- (啥都沒有)
- (Space空格)
- (空格的轉義)
- (Tab縮排)
- \r
- \n
- \f
- \t
- 可能還有,我只知道這麼多了
掌握以上知識點其實已經完全掌握在”==“的狀況下的隱式轉換了。
下面讓我們來分析一下如何判斷隱式轉換
首先,要糾正一下思維,(==)指可以進行強制型別轉換的等於比較,隱式轉換隻是在雙方屬於不同型別的時候才會觸發,遇到相同型別會直接比較。並且隱式轉換具有階段性,一會我們馬上就會遇到。
下面開始分析,看一下下面的例子
[] == 0; //true
複製程式碼
看這個例子,它符合左值為”Object“,右值為”Number“的情況,所以進行Toprimitive([]),變為
"" == 0;
複製程式碼
此時我們把這個結果叫做隱式轉換的第一階段結果,因為(==)兩邊的型別還是不相同,所以要再次進行隱式轉換,現在它符合左值為“String”,右值為“Number的情況”,所以進行ToNumber(“”),根據上面所說的特殊知識點,變為
0 == 0; //true
複製程式碼
此時為第二階段的結果,型別相同,進行比較。
下面你可以試著自己分析一下下面的例子
[null] == 0; //true
複製程式碼
不要著急,讓我們再來一個例子
[] == [null]; //false
複製程式碼
啊???怎麼回事,結果跟我們想像的好像不一樣?既然([]==0)和([null]==0),難道根據這兩個結果不應該是推匯出([]==[null])嘛?原因在於你沒有遵守我們分析的隱式轉換原則,只有不同型別才會進行隱式轉換,但是現在我們比較的兩個值是相同的型別!
以上內容同樣適用於(<)和(>)
但是要注意(<=)和(>=),他在引擎中會被處理成不大於和不小於,如:
a<=b ---> !(a>b)
複製程式碼
為什麼要說這點?試著輸出下面的例子你就明白了
var a= {b:1};
var b= {b:2};
console.log(a>b); //false
console.log(a==b); //false
console.log(a>=b); //true
複製程式碼