JS-數組之間相等操做符、布爾操做符、隱試轉換

前言

問題場景:
在作一個後臺返回數據是否有值的處理操做時,用if判斷髮現的一個有意思的問題
代碼以下:
複製代碼
後臺返回數據即:res.data.list = []
    
    if(res.data.list == []){
        console.log('無數據返回')
    }
    else
    {
        console.log('有數據')
    }
    
    打印結果:有數據
複製代碼

問題引伸

發現這個問題後就作了一些測試,測試代碼以下:面試

console.log("Boolean([]):",Boolean([]),"Boolean(![]):",Boolean(![]))
    //Boolean([]): true Boolean(![]): false
    
    console.log("[]==[]:",[]==[],"![]==[]",![]==[])
    // []==[]: false ![]==[] true
    
    console.log("+[]==[]:",+[]==[],"!(+[])==[]",!(+[])==[])
    // +[]==[]: true !(+[])==[] false
    
    console.log("-[]==[]:",-[]==[],"!(-[])==[]",!(-[])==[])
    // -[]==[]: true !(-[])==[] false
    
    console.log("[]==true:",[]==true,"[]==false:",[]==false)
    // []==true: false []==false: true
    
    console.log("![]==true:",![]==true,"![]==false:",![]==false)
    // ![]==true: false ![]==false: true
    
複製代碼

要點一

falsy(假值)、truthy(真值)數組

falsy(假值): 在 JavaScript 中只有 7 個 falsy 值。

false	false 關鍵字

0	數值 zero	

0n	當 BigInt 做爲布爾值使用時, 聽從其做爲數值的規則. 0n 是 falsy 值.

"", '', ``	這是一個空字符串 (字符串的長度爲零). JavaScript 中的字符串可用雙引號 "", 單引號 '', 或 模板字面量 `` 定義。

null	null - 缺乏值

undefined	undefined - 原始值

NaN	NaN - 非數值

複製代碼
truthy(真值):
在 JavaScript 中,truthy(真值)指的是在布爾值上下文中,轉換後的值爲真的值。
全部值都是真值,除非它們被定義爲 假值(即除 false、0、""、null、undefined 和 NaN 之外皆爲真值。

複製代碼

要點二

首先:數組的原型中有(繼承了)對象原型!---不知道這麼說合不合適
複製代碼

布爾操做符 --> ! 邏輯非bash

邏輯非操做符首先會將它的操做數轉換爲布爾值,而後再對其求反。
    若是操做數是一個對象,返回 false;
    若是操做數是一個空字符串,返回true;
    若是操做數是一個非空字符串,返回false;
    若是操做數是數值0,返回true;
    若是操做數是任意非0數值(包括Infinity),返回false;
    若是操做數是null,返回true;
    若是操做數是NaN,返回true;
    若是操做數是undefined,返回true;
列:
    alert(!false); //true
    alert(!"blue");//false
    alert(!0); //true
    alert(!NaN); //true
    alert(!""); //true
    alert(!12345);//false
複製代碼

相等操做符 --> ==測試

相等操做符(==),若是兩個操做數相等,則返回true。
相等和不想等操做符都會先轉換操做數(一般稱爲強制轉型),而後再比較他們的相等性;
    
*.在轉換不一樣的數據類型時,相等和不想等操做符遵循如下規則:
    >若是一個操做數時布爾值,則在比較相等性以前先將其轉換爲數值---false轉換爲0,true轉換爲1;
    >若是一個操做數是字符申,另個操做數是數值, 在比較相等性以前先將字符串轉換爲數值;
    >若是一個攆做數是對象,另外一個操做數不是,
    則調用對象的valueOf()方法(若是沒有獲得基本類型-->[],則調用對象的toString()方法-->""),
    用獲得的基本類型值按照前面的規則進行比較;
*.這兩個操做符在進行比較時則要遵循下列規則:
    >與null和undef ined是相等的。
    >要比較相等性以前,不能將null和undefined轉換成其餘任何值。
    >若是有一個操做數是NaN,則相等操做符返回false,而不相等操做符返回true;
    重要提示:即便兩個操做數都是NaN,相等操做符也返回false;
    由於按照規則,NaN不等於NaN。
    >若是兩個操做數都是對象,則比較它們是否是同一個對象。
    若是兩個操做數都指向同一個對象,則相等操做符返回true;不然,返回false.
複製代碼

總結

let model = []
    console.log(model,model.toString())
    //[],""
    
    /**
      * []轉換Boolean型時,回把[]看做一個對象,即任何對象轉爲Boolean型 ,返回 true
      * !在操做對象時返回false
      */
    console.log("Boolean([]):",Boolean([]),"Boolean(![]):",Boolean(![]))
    //Boolean([]): true Boolean(![]): false
    
    /**
      * []==[] 看做爲兩個對象之間的相等操做比較 --> 不是同一個對象--> false
      * ![]==[] 首先 左邊 布爾操做符![]-->!true-->false
      * 右邊分析--> []看做爲對象 調用valueOf()沒有獲得基本類型,調用toString()方法--> "" --> 空字符串轉換布爾型爲 false
      * 結果 false == false --> 
      * 若是一個操做數時布爾值,則在比較相等性以前先將其轉換爲數值 --> 0 == 0 --> true
      */
    console.log("[]==[]:",[]==[],"![]==[]",![]==[])
    // []==[]: false ![]==[] true
    
    /**
      * 左邊分析--> +[]看做爲對象 調用toString()方法--> +"" --> 0
      * 右邊 --> [] --> 調用valueOf()沒有獲得基本類型,調用toString()方法--> "" --> 空字符串轉換布爾型爲 false
      * 若是一個操做數時布爾值,則在比較相等性以前先將其轉換爲數值 --> 結果 0 == false
      * 若是一個操做數時布爾值,則在比較相等性以前先將其轉換爲數值 --> 0 == 0 --> true
      */
    console.log("+[]==[]:",+[]==[],"!(+[])==[]",!(+[])==[])
    // +[]==[]: true !(+[])==[] false
    
    /**
      * 左邊分析--> -[]看做爲對象 調用toString()方法--> -"" --> -0
      * 右邊 --> [] --> 調用valueOf()沒有獲得基本類型,調用toString()方法--> "" --> 空字符串轉換布爾型爲 false
      * 若是一個操做數時布爾值,則在比較相等性以前先將其轉換爲數值 --> 結果 0 == false --> -0 == 0 --> true
      */
    console.log("-[]==[]:",-[]==[],"!(-[])==[]",!(-[])==[])
    // -[]==[]: true !(-[])==[] false
    
     /**
      * 左邊分析--> []看做爲對象 調用valueOf()沒有獲得基本類型,調用toString()方法--> ""
      * 即 "" == true
      * 若是一個操做數時布爾值,則在比較相等性以前先將其轉換爲數值 --> 0 == 1 --> false
      * "" == false --> 0 == 0 --> true
      */
    console.log("[]==true:",[]==true,"[]==false:",[]==false)
    // []==true: false []==false: true
    
    /**
      * ![] 布爾操做符![]-->!true-->false
      * 結果 false == true --> 0 == 1 --> false
      * 結果 false == false --> 0 == 0 --> true
      */
    console.log("![]==true:",![]==true,"![]==false:",![]==false)
    // ![]==true: false ![]==false: true

複製代碼

結語

實際開發中要避免上述的隱試轉換問題。
更有利於開發中代碼的可讀性。
可是又是一些比較基礎的問題,面試可能會被問到。複製代碼
相關文章
相關標籤/搜索