視訊課程-空陣列的比較-冰山工作室-沙翼-web前端

冰山工作室發表於2019-03-26

課程視訊--空陣列的比較
提取碼:sjgy

一、引子

先上題,得出心中答案,開啟瀏覽器點開F12,複製下面程式碼,看看結果。

console.log( [] == ![] )
console.log( {} == !{} )
複製程式碼

剖析一下,主要分為:

  • !邏輯運算子的優先順序
  • {}與[]複雜資料型別如何轉換
  • == JS的資料型別的強制轉換比較

二、邏輯運算子的優先順序

運算子優先順序本身是一種規則,該規則在計算表示式時控制運算子執行的順序。具有較高優先順序的運算子先於較低優先順序的運算子執行。

先看MDN運算子優先順序圖表擷取:

優先順序 運算型別 關聯性 運算子
20 圓括號 n/a ( … )
19 new (帶引數列表) 從左到右 new … ( … )
函式呼叫 從左到右 … ( … )
16 邏輯非 從右到左 ! …
一元加法 從右到左 + …
一元減法 從右到左 - …
10 等號 從左到右 … == …
6 邏輯與 從左到右 … && …
5 邏輯或 從左到右

MDN完整地址

在擷取的表格中可以清晰的看到,邏輯非 ! 的優先順序明顯高於 == 等號的有優先順序,因此第一個問題,在 [] == ![] 中最優先運算的是 ![] ,然後才是 == 比較。

三、複雜的資料型別如何轉換

console.log(![]) // false ,這個結果相對好理解
// 注意: !帶有隱式轉換
複製程式碼
  • 1、undefined(未定義,找不到值時出現)
  • 2、null(代表空值)
  • 3、false(布林值的false,字串"false"布林值為true)
  • 4、0(數字0,字串"0"布林值為true)
  • 5、NaN(無法計算結果時出現,表示"非數值";但是typeof NaN==="number")
  • 6、""(雙引號)或''(單引號) (空字串,中間有空格時也是true)

6種值轉化為布林值時為 false 。
當前結論 ![] == false
當然,在使用 == 時永遠不要大意!參見 附1


接下來,難題在於, [] 如何轉化進行比較。
請先記住一個比較的基本規則:

陣列與數值進行比較,會先轉成數值,再進行比較;與字串進行比較,會先轉成字串,再進行比較;與布林值進行比較,兩個運運算元都會先轉成數值,然後再進行比較。

遵循上邊的規則(左側x為陣列時),需要將 [] 與 false 一併轉化為數字型別後再進行比較。
OK,那麼這個規則是誰說的算的呢?
擷取一張知乎大佬貼的Es5 規範元知識圖,上述比較參見 7 條。附2(中文版)

視訊課程-空陣列的比較-冰山工作室-沙翼-web前端
參照第7條

ToNumber(false) // 0

為啥呢?上圖

視訊課程-空陣列的比較-冰山工作室-沙翼-web前端

[] 依照圖1,進入第9條,使用 ToPrimitive([]) ,上圖

視訊課程-空陣列的比較-冰山工作室-沙翼-web前端
好吧,要根據型別預設使用 DefaultValue 方法,上圖

視訊課程-空陣列的比較-冰山工作室-沙翼-web前端

視訊課程-空陣列的比較-冰山工作室-沙翼-web前端
[] 屬於字串hint,那麼執行 toString()

console.log([].toString()) // "";


終於,表示式看起來不費勁了

"" == false ;

其實現在我們已經看到答案了,但是依據Es5 == 的規範,我們還需要將字串和布林型別轉化為數字型別最終比較;
false 參照圖2,字串參照圖1第5條

ToNumber("") // 0 ;

每次對比Es5規範非常不方便,所以

結尾總結了一下可以快速判斷==轉化判斷依據的原則,不必每次都參照圖1啦 -附3

完美, 0 == 0 // true


附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 的意思是回車換行
複製程式碼

附2

視訊課程-空陣列的比較-冰山工作室-沙翼-web前端

附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

引用原地址:

四、關於我們

視訊課程網盤地址-----傳送門 提取碼: sjgy

冰山社團官網地址-----傳送門

如果觀看視訊或文件後,你覺得有些收穫,願意加入冰山社團與我們一同成長,請進入我們的官網,點選冰山社團,加入我們~

相關文章