方格精選

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

更新於 發佈於 閱讀時間約 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
查看全部
avatar-img
發表第一個留言支持創作者!
在剛開始寫 JavaScript 可能大多數的人不會特別意識到 JavaScript 的型別系統有什麼特別之處,我是在看完 Youtube 上 CS50 的課程,才理解到在不同的程式語言中,會因為語言的特性而有不同的系統,JavaScript 就是偏向比較特別的那一種。
在前端開發中,很常會有需要轉址的需求,且處理的手法滿因人而異的,所以今天就想要來整理一些常見的 JavaScript 頁面轉址方式,以及各自的差異。
Functional Programming 中文譯作函式程式設計,或是功能性程式設計,常簡稱為:FP,是一種透過使用純函式(Pure Funciton)進行軟體開發,且避免副作用的程式設計典範,比起宣告式的流程控制,在 FP 採用主要以表達式的方式撰寫程式碼。
Hoisting 可以說是 ES6 問世之後,去面試還是會爾偶被問到的面試考題,雖然 Hoisting 離 Modern JavaScript 的技術有點距離,實作上幾乎不太會用到,但透過了解 Hoisting 的概念,可以對這門語言有更深的了解與掌握度。
對於剛接觸前端開發不久的人來說,可能會對var、let 與 const 的差異略懂略懂,但又說不太出三者實際哪裡不一樣。
在一開始學習前端開發的時候,一直遇到講師在課程內容中提到 ES5、ES6 等關鍵字,當初的我,單純認為 ES5、ES6 是講述 JavaScript 的版本,所以在使用上就沒有想太多,反正就是 JavaScript 1.0 、2.0 的感覺吧?
在剛開始寫 JavaScript 可能大多數的人不會特別意識到 JavaScript 的型別系統有什麼特別之處,我是在看完 Youtube 上 CS50 的課程,才理解到在不同的程式語言中,會因為語言的特性而有不同的系統,JavaScript 就是偏向比較特別的那一種。
在前端開發中,很常會有需要轉址的需求,且處理的手法滿因人而異的,所以今天就想要來整理一些常見的 JavaScript 頁面轉址方式,以及各自的差異。
Functional Programming 中文譯作函式程式設計,或是功能性程式設計,常簡稱為:FP,是一種透過使用純函式(Pure Funciton)進行軟體開發,且避免副作用的程式設計典範,比起宣告式的流程控制,在 FP 採用主要以表達式的方式撰寫程式碼。
Hoisting 可以說是 ES6 問世之後,去面試還是會爾偶被問到的面試考題,雖然 Hoisting 離 Modern JavaScript 的技術有點距離,實作上幾乎不太會用到,但透過了解 Hoisting 的概念,可以對這門語言有更深的了解與掌握度。
對於剛接觸前端開發不久的人來說,可能會對var、let 與 const 的差異略懂略懂,但又說不太出三者實際哪裡不一樣。
在一開始學習前端開發的時候,一直遇到講師在課程內容中提到 ES5、ES6 等關鍵字,當初的我,單純認為 ES5、ES6 是講述 JavaScript 的版本,所以在使用上就沒有想太多,反正就是 JavaScript 1.0 、2.0 的感覺吧?
你可能也想看
Google News 追蹤
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
在前端開發的世界中,有許多工具和技術能幫助我們有效地建立、維護和優化應用。本文將探討如何下載Node.js、使用CDN獲取套件、使用npm下載和管理套件、以及打包與tree-shaking的概念,這部分是前端很常會使用到的喔。 下載Node.js Node.js是前端開發中不可或缺的工具,它
Thumbnail
本章節旨在介紹 TypeScript 的基本資料型別,包括內建型別、型別轉換、自訂型別、元組、集合、陣列、和字典型別。透過理解和使用這些型別,可以提高代碼的可讀性和可維護性。
Thumbnail
TypeScript是一種由Microsoft開發和維護的開源編程語言。它是JavaScript的超集,主要擴展了JavaScript的語法,增加了靜態類型檢查和其他特性,使得開發大型應用程序更為方便和可靠。
Thumbnail
這些章節的目的是為了介紹JavaScript中的各種數據類型,包括基礎類型和物件類型,以及如何將數據從一種類型轉換為另一種類型。此外,還介紹了如何創建自定義類型,以及如何使用JavaScript中的陣列、集合和字典。
Thumbnail
在本章節中,我們將學習JavaScript的基本語法,包括如何註解代碼和如何聲明變數。瞭解這些基礎知識對於進一步學習和使用JavaScript來編寫代碼是非常重要的。
Thumbnail
JavaScript是一種具有動態型別、弱型別、原型繼承等特性的高級腳本語言,應用範圍廣泛,包括前端開發、後端開發、移動應用等。它被各種公司和開源社區廣泛使用。學習JavaScript需要掌握ECMAScript標準、異步編程、模塊系統等知識。
Thumbnail
在前端的開發中,除了切版與串 API 外,大部分的時間都在針對表單內容進行檢核、驗證、阻擋,一方面是讓使用者在操作頁面的過程中有良好的使用者體驗,不會因為一些例外狀況(Edge Case),例如:莫名其妙的 4xx 錯誤,導致使用者卡在某個操作流程中逃不出來,另一方面是讓傳遞到後端的資料更加正確⋯⋯
Thumbnail
在 2021 年的剛轉職成為前端工程師的時候,我在面試時滿常會被詢問到 JavaScript 中閉包的議題,當時候自己回答的滿差的,於是在 2022 年時,我寫了一系列的有關於函式程式設計鐵人賽的文章, 裡頭就有簡單提到有關於閉包的議題。
Thumbnail
在之前的文章當中曾經提到過 JavaScript 中的物件有一個特別的機制:傳參考(Called by reference),如果正確性再高一點的話,則可以稱之為傳共享(Called by sharing)。
Thumbnail
在先前的型別文章中,我們曾經聊過 JavaScript 常用的一些型別,但針對布林這個型別,我們沒有做太多的解釋,原因在於布林值在 JavaScript 會有一個特殊的規則:自動轉型 。 自動轉型可說是讓 JavaScript 為弱型別、且難以管理的最重要的要素,接著就來讓我們來聊聊什麼是自動轉型
Thumbnail
大家好,我是woody,是一名料理創作者,非常努力地在嘗試將複雜的料理簡單化,讓大家也可以體驗到料理的樂趣而我也非常享受料理的過程,今天想跟大家聊聊,除了料理本身,料理創作背後的成本。
Thumbnail
哈囉~很久沒跟各位自我介紹一下了~ 大家好~我是爺恩 我是一名圖文插畫家,有追蹤我一段時間的應該有發現爺恩這個品牌經營了好像.....快五年了(汗)時間過得真快!隨著時間過去,創作這件事好像變得更忙碌了,也很開心跟很多厲害的創作者以及廠商互相合作幫忙,還有最重要的是大家的支持與陪伴🥹。  
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
在前端開發的世界中,有許多工具和技術能幫助我們有效地建立、維護和優化應用。本文將探討如何下載Node.js、使用CDN獲取套件、使用npm下載和管理套件、以及打包與tree-shaking的概念,這部分是前端很常會使用到的喔。 下載Node.js Node.js是前端開發中不可或缺的工具,它
Thumbnail
本章節旨在介紹 TypeScript 的基本資料型別,包括內建型別、型別轉換、自訂型別、元組、集合、陣列、和字典型別。透過理解和使用這些型別,可以提高代碼的可讀性和可維護性。
Thumbnail
TypeScript是一種由Microsoft開發和維護的開源編程語言。它是JavaScript的超集,主要擴展了JavaScript的語法,增加了靜態類型檢查和其他特性,使得開發大型應用程序更為方便和可靠。
Thumbnail
這些章節的目的是為了介紹JavaScript中的各種數據類型,包括基礎類型和物件類型,以及如何將數據從一種類型轉換為另一種類型。此外,還介紹了如何創建自定義類型,以及如何使用JavaScript中的陣列、集合和字典。
Thumbnail
在本章節中,我們將學習JavaScript的基本語法,包括如何註解代碼和如何聲明變數。瞭解這些基礎知識對於進一步學習和使用JavaScript來編寫代碼是非常重要的。
Thumbnail
JavaScript是一種具有動態型別、弱型別、原型繼承等特性的高級腳本語言,應用範圍廣泛,包括前端開發、後端開發、移動應用等。它被各種公司和開源社區廣泛使用。學習JavaScript需要掌握ECMAScript標準、異步編程、模塊系統等知識。
Thumbnail
在前端的開發中,除了切版與串 API 外,大部分的時間都在針對表單內容進行檢核、驗證、阻擋,一方面是讓使用者在操作頁面的過程中有良好的使用者體驗,不會因為一些例外狀況(Edge Case),例如:莫名其妙的 4xx 錯誤,導致使用者卡在某個操作流程中逃不出來,另一方面是讓傳遞到後端的資料更加正確⋯⋯
Thumbnail
在 2021 年的剛轉職成為前端工程師的時候,我在面試時滿常會被詢問到 JavaScript 中閉包的議題,當時候自己回答的滿差的,於是在 2022 年時,我寫了一系列的有關於函式程式設計鐵人賽的文章, 裡頭就有簡單提到有關於閉包的議題。
Thumbnail
在之前的文章當中曾經提到過 JavaScript 中的物件有一個特別的機制:傳參考(Called by reference),如果正確性再高一點的話,則可以稱之為傳共享(Called by sharing)。
Thumbnail
在先前的型別文章中,我們曾經聊過 JavaScript 常用的一些型別,但針對布林這個型別,我們沒有做太多的解釋,原因在於布林值在 JavaScript 會有一個特殊的規則:自動轉型 。 自動轉型可說是讓 JavaScript 為弱型別、且難以管理的最重要的要素,接著就來讓我們來聊聊什麼是自動轉型