首先我們要知道,在 JS 中類型轉換只有三種情況,分別是:
- 轉換為布爾值
- 轉換為數字
- 轉換為字符串
我們先來看一個類型轉換表格
轉Boolean
在條件判斷時,除了 undefined
, null
, false
, NaN
, ''
, 0
, -0
,其他所有值都轉為 true
,包括所有對象。
對象轉原始類型
對象在轉換類型的時候,會調用內置的 [[ToPrimitive]]
函數,對於該函數來說,算法邏輯一般來說如下:
- 如果已經是原始類型了,那就不需要轉換了
- 調用
x.valueOf()
,如果轉換為基礎類型,就返回轉換的值 - 調用
x.toString()
,如果轉換為基礎類型,就返回轉換的值 - 如果都沒有返回原始類型,就會報錯
當然你也可以重寫 Symbol.toPrimitive
,該方法在轉原始類型時調用優先級最高。
let a = { valueOf() { return 0 }, toString() { return '1' }, [Symbol.toPrimitive]() { return 2 } } 1 + a // => 3
四則運算符
加法運算符不同於其他幾個運算符,它有以下幾個特點:
- 運算中其中一方為字符串,那么就會把另一方也轉換為字符串
- 如果一方不是字符串或者數字,那么會將它轉換為數字或者字符串
1 + '1' // '11' true + true // 2 4 + [1,2,3] // "41,2,3"
- 對於第一行代碼來說,觸發特點一,所以將數字
1
轉換為字符串,得到結果'11'
- 對於第二行代碼來說,觸發特點二,所以將
true
轉為數字1
- 對於第三行代碼來說,觸發特點二,所以將數組通過
toString
轉為字符串1,2,3
,得到結果41,2,3
另外對於加法還需要注意這個表達式 'a' + + 'b'
'a' + + 'b' // -> "aNaN"
因為 + 'b'
等於 NaN
,所以結果為 "aNaN"
,你可能也會在一些代碼中看到過 + '1'
的形式來快速獲取 number
類型, + ' ' => 0 。
那么對於除了加法的運算符來說,只要其中一方是數字,那么另一方就會被轉為數字
4 * '3' // 12 4 * [] // 0 4 * [1, 2] // NaN
比較運算符
- 如果是對象,就通過
toPrimitive
轉換對象 - 如果是字符串,就通過
unicode
字符索引來比較
let a = { valueOf() { return 0 }, toString() { return '1' } } a > -1 // true
在以上代碼中,因為 a
是對象,所以會通過 valueOf
轉換為原始類型再比較值。