1. 程式人生 > 實用技巧 >offer收割機--js的隱式型別轉換規則整理

offer收割機--js的隱式型別轉換規則整理

型別轉換

文中的值型別等價於所說的基礎型別,其範圍是(boolean,string,number)

轉換為基礎型別

布林值

  • undefinednullfalseNaN''0 --> false
  • 其它值都,包括所有物件 --> true

數字

  • 陣列
    • [] --> 0: 空陣列轉為0
    • [1] --> 1: 含有一個元素且為數字則轉換為數字
    • [1,2] --> NaN: 其餘情況轉為NaN
    • ['abc',1] --> NaN: 其餘情況轉為NaN
  • 值型別
    • null --> 0
    • '123' --> 123: 純數字構成的字串直接轉換為對應的數字
    • true --> 1
    • false --> 0
    • '124a' --> NaN
    • undefined --> NaN
    • Symbol --> 丟擲錯誤
  • 除了陣列之外的引用型別(Object) --> NaN

字串

  • 666 --> '666': 數字可直接轉為字串
  • 布林值:布林值直接轉換
    • true --> 'true'
    • false --> 'false'
  • 陣列
    • [] --> '' :空陣列轉為空串
    • [2,'3'] --> '2,3' :非空陣列的每一項轉為字串再用,分割
  • 物件:
    • {} --> [object Object]
    • {a:1} --> [object Object]

物件轉基礎型別規則

物件在轉換型別的時候,會呼叫內建的 [[ToPrimitive]] 函式,對於該函式來說,演算法邏輯一般來說如下:

  1. 如果已經是基礎型別了,那就不需要轉換了
  2. 目標型別為字串就先呼叫 toString
    • 轉換為基礎型別的話就返回轉換的值
  3. 目標型別不為字串就先呼叫 valueOf
    • 結果為基礎型別,就返回轉換的值
    • 結果不是基礎型別的話再呼叫 toString
  4. 如果都沒有返回基礎型別,就會報錯

各種情況舉例

const demo1 = {
    [Symbol.toPrimitive]: function () {
        return 2
    }
}
// 情況1
console.log(demo1 + 1); // 3

const demo2 = {
    toString() {
        return 'demo2'
    },
    valueOf() {
        return 20
    }
}
// 情況2
console.log(String(demo2)) // demo2

// 情況3-1
console.log(demo2 - 3); // 17

const demo3 = {
    toString() {
        return 30
    },
    valueOf() {
        return {}
    }
}
// 情況3-2
console.log(demo3 - 4); // 26

const demo4 = {
    toString() {
        return {}
    },
    valueOf() {
        return {}
    }
}
// 情況4
console.log(demo4 + 1); // 報錯

四則運算子

加法

  • 有一方為String,那麼另一方也會被轉為String
  • 一方為Number,另一方為原始值型別,則將原始值型別轉換為Number
  • 一方為Number,另一方為引用型別,雙方都轉為String

其它

除了加法的運算子來說(-,*,/),會將非Number型別轉換為Number型別

轉換示例

'123'+4 // '1234'

123+true // 124
123+undefined // NaN
123+null // 123

123+[] //  '123'
123+{} // '123[object Object]'

比較運算子

==

  1. NaN不等於任何其它型別
  2. Boolean 與其它型別進行比較,Boolean轉換為Number
  3. StringNumber進行比較,String 轉化為Number
  4. nullundefinde進行比較結果為true
  5. null,undefined與其它任何型別進行比較結果都為false
  6. 引用型別值型別進行比較,引用型別先轉換為值型別(呼叫[ToPrimitive])
  7. 引用型別引用型別,直接判斷是否指向同一物件

舉例

[]==![] // true
// [] == false  1. 根據運算子優先順序 ![] --> false
// [] == 0      2. 上面規則2
// '' == 0      3. 上面規則6
//  0 == 0      4. 上面規則3
// 所以結果為true

參考

思否-前端碎碎念 之 為什麼[] == ![] ?

freeCodeCamp-Javascript 隱式型別轉換,一篇就夠了