JavaScript 隱式類型轉換規則詳解
前言
在 JavaScript 中,在進行運算操作時,如果兩邊數據不統一,這時我們編譯器會自動將運算符兩邊的數據做一個數據類型轉換再進行計算。這種由編譯器進行自動轉換的方式被稱為隱式轉換。
數學運算符中的類型轉換
減、乘、除
在對非 Number
類型運用數學運算符(-
、*
或 /
)時,會先將非 Number
類型轉換為 Number
類型再進行計算。示例如下:
2 - true // 結果為 1,首先把 true 轉換為數字 1,然後執行 2 - 1 2 - null // 結果為 0,首先把 null 轉換為數字 0,然後執行 2 - 0 2 - undefined // 結果為 NaN,因為 undefined 被轉換為 NaN,然後執行 2 - NaN 2 * '5' // 結果為 10,'5' 首先會變成數字 5, 然後執行 2 * 5
註意:在算術運算中,如果操作數中有 undefined
,其運算結果是就是 NaN
;null
在算術運算中則是隱式轉換為數值 0
來參與運算。
加
為什麼加法要區別對待?因為 js 中 +
還可以用來拼接字符串。
加法運算遵守以下 3 條規則,優先級從高到低
當一側為 String
類型,被識別為字符串拼接,並會優先將另一側轉換為字符串類型。
當一側為 Number
類型,另一側為原始類型,則將原始類型轉換為 Number
類型。
當一側為 Number
類型,另一側為引用類型,將引用類型和 Number
類型轉換成字符串後拼接。
示例如下:
123 + '123' // 246 (規則1) 123 + null // 123 (規則2) 123 + true // 124 (規則2) 123 + undefined // NaN (規則2) 123 + {} // 123[object Object] (規則3)
邏輯語句中的類型轉換
單個變量
如果隻有單個變量,會先將變量轉換為 Boolean
值。隻有 null
、undefined
、''
、NaN
、0
、 false
這幾個會被轉換為 false
,其他的情況都是 true
,比如 {}
, []
等。示例如下:
if (null) { console.log('111') } else { console.log('222') } // 輸出 222
使用 == 比較
使用 ==
比較,比較規則如下:
NaN
和其他任何類型比較永遠返回 false
(包括和它自己)。
Boolean
和其他任何類型比較,Boolean
首先被轉換為 Number
類型。
String
和 Number
比較,先將 String
類型轉換為 Number
類型。
null == undefined
比較結果是 true
,除此之外,null
、undefined
和其他任何類型的比較都為 false
。
原始類型
和 引用類型
比較時,引用類型會依照 ToPrimitive
規則轉換為原始類型。(ToPrimitive 在下面有解釋)
示例如下:
NaN == NaN // false (規則1) // (規則2) true == 1 // true true == '1' // true true == '2' // false true == ['1'] // true, 先把 true 變成 1, ['1'] 拆箱成 '1', 再參考(規則3) true == ['2'] // false, 同上 // (規則3) 123 == '123' // true '' == 0 // true // (規則4) null == undefined // true null == '' // false null == 0 // false null == false // false undefined == '' // false undefined == 0 // false undefined == false // false // (規則5) '[object Object]' == {} // true, 字符串和對象比較,對象通過 toString 得到一個基本類型值 '1,2,3' == [1,2,3] // true, 同上,[1,2,3] 通過 toString 得到一個基本類型值
ToPrimitive
ToPrimitive
規則會嘗試調用對象的 valueOf
和 toString
方法,將參數轉換為原始類型。
當對象類型需要轉為原始類型時,它會先查找對象的 valueOf
方法,如果 valueOf
方法返回原始類型的值,則 ToPrimitive
的結果就是這個值,如果 valueOf
不存在或者 valueOf
方法返回的不是原始類型的值,就會嘗試調用對象的 toString
方法,也就是會遵循對象的 ToString
規則,然後使用toString
的返回值作為 ToPrimitive
的結果。
示例如下:
let str = new String(1) // 通過 new String 創建瞭一個對象 console.log(typeof str) // object console.log(str.valueOf()) // "1" console.log(typeof str.valueOf()) // string const obj = { valueOf() { return 1 }, toString() { return 2 } } console.log(Number(obj)) // 1
註意:如果 valueOf
和 toString
都沒有返回原始類型的值,則會拋出異常。
示例如下:
const obj = { valueOf() { return [] }, toString() { return {} } } console.log(Number(obj)) // TypeError: Cannot convert object to primitive value
特殊:
String({}) // [object Object] Number([]) // 0
String({})
空對象會先調用 valueOf
,但返回的是對象本身 {}
,不是原始類型,所以會繼續調用toString
,得到 [object Object]
,String([object Object])
,所以轉換後的結果為 [object Object]
。
Number([])
空數組會先調用 valueOf
,但返回的是數組本身 []
,不是原始類型,所以會繼續調用toString
,得到 ''
,相當於 Number('')
,所以轉換後的結果為 0
。
以上就是JavaScript 隱式類型轉換規則詳解的詳細內容,更多關於JavaScript 隱式類型轉換的資料請關註WalkonNet其它相關文章!
推薦閱讀:
- JavaScript原始值與包裝對象的詳細介紹
- JavaScript數據類型轉換詳解(推薦)
- 一篇文章讓你輕松記住js的隱式轉化
- 分享JavaScript 類型判斷的幾種方法
- 一篇文章弄懂js中的typeof用法