在先前的型別文章中,我們曾經聊過 JavaScript 常用的一些型別,但針對布林這個型別,我們沒有做太多的解釋,原因在於布林值在 JavaScript 會有一個特殊的規則:自動轉型 。
自動轉型可說是讓 JavaScript 為弱型別、且難以管理的最重要的要素,接著就來讓我們來聊聊什麼是自動轉型吧。
在 JavaScript 中,並沒有限定型別一定要一樣才能進行運算,這是什麼意思呢?舉例來說:我們可以拿字串與數字進行累加:
1 + '1'
// ?
也可以拿不同型別的值來進行比較:
1 > '1'
// ?
1 === '1'
// ?
0 == false
// ?
顯然其中有詐,要不是 JavaScript 有做一些什麼事,不然怎麼會讓不同型別間進行比較呢?這是因為,JavaScript 會依照當下運算情境,來決定是不是要替其中的值自動做轉型,這個過程就是我們所常聽到的自動轉型了,接著我們來看一些常見的轉型規則與情境吧!
以下是一些 JavaScript 常見的轉型規則:
JavaScript 真的是一個很神奇的語言,字串型別與數字型別可以相加到底是指什麼?舉例來說:把字串 ‘ Vivian’ 加上數字 1 結果會是什麼?
以常理來說我們沒有辦法拿非數字的東西與數字來進行大小的比較,或是進行加減乘除,於是聰明的 JavaScript 在遇到字串與數字邏輯運算時,會把字串或是數字去做一些轉型,很酷吧?
讓我們來看一些常見的數字轉字串的自動轉型:
1 + '1'
// '11'
Number()
的方法將字串轉為數字看看,但也有可能字串無法轉型而導致出錯,出現 NaN
(非數字)的型別出現:2 - '1'
// 1
'vvn' - 1
//NaN
'vvn' * 8
// NaN,不會出現 8 個 vvn 喔
'vvn' / 2
// NaN
在先前的文章中,我們曾經提到布林是 JavaScript 奇怪機制的其中一員,除了自動轉型的機制外,我們還會討論一個延伸議題:真值與假值。
JavaScript 型別基本上都可以被轉成布林值,能被轉為 true 稱為真值(Truthy Value),被轉為 false 的為假值(Falsy Value),因為真值的情境舉不完,我們直接來看哪一些型別可以被轉為假值,我們可以用 Boolean 這個方法來檢核:
Boolean(0);
// false
Boolean('');
// false
Boolean(undefined);
// false
Boolean(null);
// false
Boolean(NaN);
// false
Boolean(false);
// false,別忘記 false 本身也是一種假值
以上就是 6 種 JavaScript 假值的狀況,很多初級的前端工程師面試算是必考的題目,一開始大家可能都會想要用背的,不過對有一些開發經驗的人來說,可能會發現一些端倪。
假值的情境基本上是「容易出錯」、「空值、未定義」的情境,舉例來說:當資料要呈現在畫面上時,我們不會希望當沒有資料時,出現「空殼」似的 UI ,或是在一些資料型別錯誤時,這些資料還是會如實出現在頁面上,這都是需要被避免掉的。
通常在條件判斷時,例如:使用三元運算子、 if else
判斷式時, JavaScript 會需要將比對邏輯轉為布林值,所以我們就必須理解 JavaScript 自動轉型的規則,才能在這些時機點寫出嚴謹的判斷,而不是因為自動轉型的規則導致流程判斷結果異常。
為了優化流程判斷,實務開發時有許多工程師會將判斷假值寫成一個共用函式:
const isEmpty= (value) => value === ''|| value === undefined|| value === null;
在需要的時候引入函式,就可以減少誤用假值的狀況出現,這邊還要注意一個狀況,實務上的空陣列與空物件並不是假值,至於如何檢核空陣列與空物件的情境,之後有機會再跟大家聊聊。
JavaScript 中的型別都可以轉成布林,而布林值在有些情境下也會進行自動轉型,以下內容比較跟實務開發無關,比較是 JavaScript 這門語言的特性,面試也許會考到。
// 布林值遇到數字運算時,會跟字串一樣先用 Number() 來進行轉型
// true -> 1, false -> 0
true > 0
// -> true
false < 1
// -> true
下方的情境又更加神奇了一點:
// 遇到累加時,要看運算對象中有沒有字串決定轉型規則
// 若布林值的運算對象為數字,則先使用 Number() 轉型布林值
// 若布林值的運算對象為字串,則先使用 toString() 轉型為字串
// 註:要搭配 JavaScript 中的優先序一起看
true + 1
// -> 2
true + 1 + '1'
// -> '21'
true + (1 + '1')
// -> 'true11'
2 + false + 1
// -> 3
要避免自動轉型的話有幾種方式:
自己覺得流程判斷的控制很看開發者自己的習慣,上述方法都是平常我會用來避免 JavaScript 自動轉型出現錯誤的方式,與大家分享。
這篇文章不是很教科書式的分享「自動轉型」或是「真值、假值」這個面試題,而是參雜了一些自己實務上的開發經驗,讓大家理解這個議題不僅僅是面試題而已,還是一個前端工程師非常重要的基礎,在工作上也會持續的遇到,並且要透過理解這在機制找更好的方式處理預期外錯誤。
希望這篇文章會對「自動轉型」、「真值、假值」有疑慮的人有幫助,我是 Vivian ,我們下次見。