JavaScript 型別轉換的那些事

在 JavaScript 裡常常會需要進行各種型別轉換,有時是我們意圖更好理解程式而做的,也有時會是因為運算也有時因為述句的估算而自動的進行型別轉換。

其中將基型 (primitive) 轉換為其他型別相當好懂,需要注意的是 undefined 以及 null 在轉為數字型別的時候前者為 NaN 而後者是 0。但麻煩的是在 JavaScript 中運算子會執行一些包藏禍心的型別轉換,像是:

101 + ""
// "101"
"689"+0
// "6890"
"87"-0
// 87
+"40"
// 40
!!"Taiwan"
// true

為了確定我們要的結果被正確的估算出來,還是要進行資料的格式化來精確的控制好數字與字串間的格式。在上面提到的隱含的型別轉換裡會用到物件所繼承到的兩種轉換方法:toString()valueOf()。這兩種方法會在不同的運算子執行時被調用,包括物件型別 (陣列、函式) 之間的估算。

一般來說我們在 JavaScript 中使用 + 運算子來連接字串或是將數值相加起來,但在該運算子左右的運算元的型別不同的時候 JavaScript 會自動地幫我們轉換為基型值,當這個加號為二元運算子時 (加號左右都有值) 的狀況如下:
– 若有運算元為物件時,Date 物件轉為字串 (調用自己的 toString() 方法),而其他物件由 valueOf() 轉換,若沒有 valueOf() 的方法時則再去調用 toString() 方法轉換出來。
– 運算元轉為基型值之後若運算元中有字串 (基型) 時則將兩運算元都轉為字串 (基型) 連接。
– 若兩運算元中都不是字串 (基型) 時兩者會被轉為數字 (基型,包括 NaN) 然後相加。

但當加號是一元運算子的時候,像上述 +"40" 的例子時,會將他的運算元轉為數字 (基型,包括 NaN):

+"-40"
// -40
+"+0"
// 0
+"-0"
// -0
+""
// 0
+undefined
// NaN
+[]
// 0
+["-7"]
// -7
+["e"]
// NaN
+[0,1]
// NaN
// 多個元素都是 NaN

瞭解了兩種加號的使用後,還要注意到二元加號運算子具有左結合率,以及運算子優先順序:

9 + (4 + "crazy")
//  "94crazy"
9 + 4 + "crazy"
// "13crazy"

在處理資料時要更加容易知道估算後的結果還是盡量先將資料進行格式化,該是字串就是字串,該是整數的化為整數,藉此也確保資料在處理中發生預期外的變化。

參考資料:

ECMAScript® 2015 Language Specification, 7.1 Type Conversion
JavaScript 大全 6e, 3.8 型別轉換
JavaScript 大全 6e, 4.8.1 + 運算子