【視訊教程】JS空資料比較-冰山工作室-沙翼-web前端
前言
先上題,得出心中答案,開啟瀏覽器點開F12,複製下面程式碼,看看結果。
console.log( [] == ![] ) console.log( {} == !{} )
剖析一下,主要分為:
- !邏輯運算子的優先順序,
- {}與[]複雜資料型別如何轉換;
- == JS的資料型別的強制轉換比較;
邏輯運算子的優先順序
運算子優先順序本身是一種規則,該規則在計算表示式時控制運算子執行的順序。具有較高優先順序的運算子先於較低優先順序的運算子執行。
先看MDN運算子優先順序圖表擷取:
優先 | 運算型別 | 關聯性 | 運算子 |
---|---|---|---|
20 | 圓括號 | n/a | (...) |
19 | new(帶引數列表) | 從左到右 | new...(...) |
函式呼叫 | 從左到右 | ..(..) | |
16 | 邏輯非 | 從右到左 | !... |
一元加法 | 從右到左 | +... | |
一元減法 | 從右到左 | -... | |
10 | 等號 | 從左到右 | ...==... |
6 | 邏輯與 | 從左到右 | ...&&... |
5 | 邏輯或 | 從左到右 | ...II... |
在擷取的表格中可以清晰的看到,邏輯非 ! 的優先順序明顯高於 == 等號的有優先順序,因此第一個問題,在 [] == ![] 中最優先運算的是 ![] ,然後才是 == 比較。
複雜的資料型別如何轉換
console.log(![]) // false ,這個結果相對好理解 // 注意: !帶有隱式轉換
- undefined(未定義,找不到值時出現)
- null(代表空值)
- false(布林值的false,字串"false"布林值為true)
- 0(數字0,字串"0"布林值為true)
- NaN(無法計算結果時出現,表示"非數值";但是typeof NaN==="number")
- ""(雙引號)或''(單引號) (空字串,中間有空格時也是true)
6種值轉化為布林值時為 false 。
當前結論 ![] == false ,當然,在使用 == 時永遠不要大意!參見 附1 ;接下來,難題在於, [] 如何轉化進行比較。請先記住一個比較的基本規則:
陣列與數值進行比較,會先轉成數值,再進行比較;與字串進行比較,會先轉成字串,再進行比較;與布林值進行比較,兩個運運算元都會先轉成數值,然後再進行比較。
附1:
相等運算子(==)隱藏的型別轉換,會帶來一些違反直覺的結果,下面整理一些:
0 == ''// true 0 == '0'// true 2 == true// false 2 == false// false // 參見圖1第7條 false == 'false'// false false == '0'// true false == undefined// false false == null// false null == undefined// true ' \t\r\n ' == 0// true // \t \r \n都是轉義字元,空格就是單純的空格,輸入時可以輸入空格 // \t 的意思是 橫向跳到下一製表符位置 // \r 的意思是 回車 // \n 的意思是回車換行
遵循上邊的規則(左側x為陣列時),需要將 [] 與 false 一併轉化為數字型別後再進行比較。OK,那麼這個規則是誰說的算的呢?
擷取一張知乎大佬貼的Es5 規範元知識圖,下述比較參見 7 條。 附2(中文版)
附2:
參照第7條:
ToNumber(false) // 0
為啥呢?上圖
[]依照圖2,進入第9條,使用 ToPrimitive([]) ,上圖
好吧,要根據型別預設使用 DefaultValue 方法,上圖
[]屬於字串 hint ,那麼執行 toString() ,
console.log([].toString()) // "";
終於,表示式看起來不費勁了,
"" == false ;
每次對比 Es5 規範非常不方便,所以
結尾總結了一下可以快速判斷==轉化判斷依據的原則,不必每次都參照圖2啦 - 附3
完美
0 == 0 // true
附3
- x == y同類型原則總結:
- Number比數值(+0,-0相等);
- String比長短與字元序列(charCode);
- Boolean中false == false; // true;
- 複雜資料型別比較引用地址;
- x == y不同基礎資料型別比較原則總結:
- x或y出現NaN一定返回false;
- x或y出現Boolean一定全部轉化數字後在比較;
- x或y出現Number一定全部轉化數字後比較;
- x == y 包含複雜資料型別原則:
- x或y出現複雜資料型別通過valueOf()或toString()轉化為基本資料型別, 然後參照上述規則比較;
x == y特殊總結:
- Null 與 Undefined除彼此或自身外,一律返回false;
- NaN == NaN; // false
關於我們
原始高清視訊下載
QQ答疑交流群:
600633658