Day 09
轉大人和轉職ㄧ樣不簡單
這樣一句話「JavaScript 是弱型別語言」 好像出現好幾次了,但它常出現也不是沒有原因,因為我們常常會忘記 JavaScript 會幫我們默默地 偷偷的 把資料轉型別這件事,且轉成它認為是合理的型別,但對我們而言卻是雷… 默默哭泣…。
在聊如何轉型別或轉成陣列時,先讓我們來聊聊 JavaScript 的型別轉換這件事吧。
就像犀牛大全裡面說的,JavaScript 對值的型別要求很有彈性 是沒原則吧…。例如布林值的true
和 false
偶爾會變成 1 與 0,對其他的型別也是如此,如果 JavaScript 想要字串,它會把我們給它的任何值都轉成字串; 如果它不是我們想要數字,會把我們給它的任何型別的值轉成數字 好隨心所欲與任性,偶而轉大人轉不過去,它就直接吐 NaN
Not a number 給我們。
我們來看幾個例子:
1 | let test1 = 'hello ' + 42; |
我們稱這種換換型別的方式為隱性轉型,也就是 JavaScript 自動幫我們轉型這件事。詳細的轉型資料實在太多,在「犀牛大全」裡就有 6,1/2 頁,有興趣可以參考這本犀牛,再加上「你說不知道的 JS」,一邊看一邊實作會更有感覺。其中有許多奇怪的部分,以下,只是舉出其中一個例子而已。 到底有多少規則啊!
數字和運算子的隱性轉型 implicit
在 JavaScript 有個頗怪異的現象,就是如果是「相加」,只要兩個相加數其中一個為「字串數字」如 "42"
,它就會把另一個數字也轉成字串處理。
1 | '42' + 24; // "4224" |
而這種現象只會出現在「加法」,而在減、乘、除、求餘時,卻會自動把「字串數字」轉成「數字」,而順利進行運算。
1 | '42' - 24; // 18 |
一些隱性轉型成數字的規則:
- 如果是可以解析(parse)的字串數字,就會轉成數字
- 任何不是數字字面值的字串會被轉成
NaN
true
會被轉成1
,而false
和空字串""
都會被轉成0
顯性轉型 Explicit
顯性轉換型別最簡單的方式是使用Boolean()
, Number()
, String()
或者是Object()
這些內建函式。以下是一些範例:
1 | Boolean([]); // true |
- 除了
null
和undefined
之外,任何值可使用toString()
方法,結果和使用String()
相同。 - 將
null
和undefined
轉為物件,會產生TypeError
。
針對陣列的相互轉型別
把陣列轉成字串
我們常常需要把我們的陣列轉成字串,去做其他的處理,最簡單的方式就是使用內建的toString()
函式。我們也可以使用String()
,但記得要用一個變數去接它,就可達到一樣的效果。
1 | let arr = [1, 2, 3, 4, 5]; |
把陣列裡面的值個別轉成數字
我們可以使用map()
去遍歷陣列裡的元素,並調用parseInt()
這個可以將其他型別轉成數字的函數,將每個元素轉成數字,要注意parseInt()
裡的第二個參數是進位,我們使用十進位去處理,如果沒給第二個參數,它就 會亂給你看 會有不預期的結果。
1 | let arr = ['1', '2', '3']; |
另一種寫法好神奇
1 | let arr2 = ['10', '20', '30', '40', '50']; |
如果有字面值無法轉成數字,當然就轉成代表不是數字的NaN
1 | let arr3 = ['10', '20', 'wow', '40', 'Hi']; |
類陣列(Array-like)轉為陣列
在前幾天的「陣列有哪幾種?」的篇章中,我們有介紹到陣列中的類陣列,而如何把類陣列物件中的值取出,並轉換成單純的陣列?
使用Object.values()
可得到一組只有值得陣列,也剛好可以把類陣列的值(value)取出,這個方法也同時適用在一般的物件。
1 | let obj = { |
二維陣列轉換成一維陣列
一般我們很少會自己創建多維陣列,所謂一維或二維陣列,就是在一個陣列裡,只有一組中括號,如果這組中括號裡有兩個或兩個以上的陣列(中括號),就稱為多維陣列,當我們拿到這樣的陣列,又必須用方法去處理他,這時就可以用以下的方法,達到「壓平」陣列的效果。
現確認這個陣列的長度是否是零,如果是就不用處理它了,直接回傳零,這只是一個過濾機制。接下來,先將陣列以toString()
轉成字串,在用split()
以逗號分格每個元素,最後再以Number
確保元素為數字。
1 | function flatten(arr) { |
感謝 Huli 提醒,在這個範例裡所使用的flatten()
,只會對陣列元素是數字的多維陣列起作用,其他數字以外的型別就沒辦法使用flatten()
了。
另外有幾種可以把多維陣列壓平的方法,原來MDN 上面都有範例,甚至是用遞迴的方式解決,有興趣的可以參考一下,這個「[遞迴(recurse)只應天上有, 凡人該當用迴圈(iterate)]的寫法。 本人絕對是凡人
大家有沒有發現,我們已經開始使用幾個 JavaScript 的方法在處理這些不是陣列的資料?接下來我們也會一一介紹這些內建的陣列方法喔~
如有需要改進的地方,拜託懇求請告知,我會盡量快速度修改,感謝您~