編輯嚴選
【前端基礎】關於 JavaScript 的型別系統:自動轉型、真值與假值

2024/01/25閱讀時間約 6 分鐘

在先前的型別文章中,我們曾經聊過 JavaScript 常用的一些型別,但針對布林這個型別,我們沒有做太多的解釋,原因在於布林值在 JavaScript 會有一個特殊的規則:自動轉型 。

自動轉型可說是讓 JavaScript 為弱型別、且難以管理的最重要的要素,接著就來讓我們來聊聊什麼是自動轉型吧。

自動轉型是什麼?

在 JavaScript 中,並沒有限定型別一定要一樣才能進行運算,這是什麼意思呢?舉例來說:我們可以拿字串與數字進行累加:

1 + '1'
// ?

也可以拿不同型別的值來進行比較:

1 > '1'
// ?

1 === '1'
// ?

0 == false
// ?

顯然其中有詐,要不是 JavaScript 有做一些什麼事,不然怎麼會讓不同型別間進行比較呢?這是因為,JavaScript 會依照當下運算情境,來決定是不是要替其中的值自動做轉型,這個過程就是我們所常聽到的自動轉型了,接著我們來看一些常見的轉型規則與情境吧!

自動轉型的時機規則

以下是一些 JavaScript 常見的轉型規則:

字串與數字進行邏輯運算:

JavaScript 真的是一個很神奇的語言,字串型別與數字型別可以相加到底是指什麼?舉例來說:把字串 ‘ Vivian’ 加上數字 1 結果會是什麼?

以常理來說我們沒有辦法拿非數字的東西與數字來進行大小的比較,或是進行加減乘除,於是聰明的 JavaScript 在遇到字串與數字邏輯運算時,會把字串或是數字去做一些轉型,很酷吧?

讓我們來看一些常見的數字轉字串的自動轉型:

  • 數字與字串累加:早期來沒有樣板字面值時,常常會需要多種欄位來源的字串組成一串句子,在 JavaScript 中,累加不一定是針對數字進行累加,加號運算子還可以用來進行字串的組合,如果加號運算子,左右兩側有字串及數字的話,就會將數字轉為字串型別:
1 + '1'
// '11'
  • 數字與字串相減、乘、除:當遇到減法運算子時,若是有字串型別,JavaScript 就會嘗試使用 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

如何避免自動轉型?

要避免自動轉型的話有幾種方式:

  1. 使用靜態碼分析工具 TypeScript ,詳細介紹可以參考這篇文章
  2. 搞懂 JavaScript 的轉型規則。
  3. 把假值的判斷額外封裝成函式調用。
  4. 在做流程判斷的時候把空值的情境考量進去,並進行額外的判斷。
  5. 寫預設值

自己覺得流程判斷的控制很看開發者自己的習慣,上述方法都是平常我會用來避免 JavaScript 自動轉型出現錯誤的方式,與大家分享。

這篇文章不是很教科書式的分享「自動轉型」或是「真值、假值」這個面試題,而是參雜了一些自己實務上的開發經驗,讓大家理解這個議題不僅僅是面試題而已,還是一個前端工程師非常重要的基礎,在工作上也會持續的遇到,並且要透過理解這在機制找更好的方式處理預期外錯誤。

希望這篇文章會對「自動轉型」、「真值、假值」有疑慮的人有幫助,我是 Vivian ,我們下次見。

為了追求可以窩在座位上、可以心無旁騖思考問題、座位可以亂七八糟沒關係、不需要到處哈腰點頭跑客戶,不用腳踩十公分、連妝都可以不用化的職場人生,文組少女毅然決然踏上RD的養成日常。
留言0
查看全部
發表第一個留言支持創作者!