Karen Huang
8 min readOct 23, 2021

ㄟ問你喔,強制轉型是什麼?轉換型別有規則可循嗎?(布林值、字串篇)

Photo by True Agency on Unsplash

要開始探討 JavaScript 的強制轉型(coercion),也一樣是在談資料型別間如何轉換的問題,但因為不太可能記起所有的轉型變化,只能盡可能地去理解轉型的規則了。

  1. 強制轉型有分「顯性轉型 (explicit coercion) 」及「隱性轉型 (implicit coercion) 」。
  2. 強制轉型將轉出:布林值、字串、數字。
  3. 原始型別和物件型別這兩種值的轉換邏輯會不大一樣。(但目前只會先著重在紀錄原始型別的強制轉型)

那什麼是顯性轉型?什麼又是隱性轉型?

簡單來說,顯性轉型是透過人工的方式,以函式的方法轉換值的型別;而隱性轉型則是由 JS 來幫你轉。

但總之,不管是人工透過函式或直接由 JS 幫你轉,只會轉出布林值、字串、數字這三種型別。

而在進入正題前,要先說明,本文主要是參考 JavaScript type coercion explained 這篇文章分類的方式,再依我自己認為由簡單到複雜的程度,分別由布林值、字串、數字的順序來解釋強制轉型及其規則。

一、布林值的顯性與隱性轉型

布林值的顯性轉型:

如前言所述,顯性轉型是必須以人工方式透過函式的方法來進行型別的轉換,因此就以 Boolean(); 來舉例,不論是任何型別的值丟進函式 Boolean(),都會轉出布林值的結果。

其中如果是屬於 falsy 值的,透過函式則會轉出 false,而屬於 truthy值的,在 Boolean() 也會轉出 true,至於 truthy值與 falsy值到底怎麼分,可參閱下表的整理。

轉出結果為 false 的組別
console.log(Boolean(null)); // false console.log(Boolean(undefined)); // false
console.log(Boolean(-0)); //false
console.log(Boolean(+0)); //false
console.log(Boolean(NaN)); //false
console.log(Boolean("")); //false
轉出結果為 true 的組別
console.log(Boolean(" ")); //true
console.log(Boolean("0")); //true
console.log(Boolean("1")); //true
console.log(Boolean(1)); // true
console.log(Boolean("hello")); //true
console.log(Boolean({})); //true
console.log(Boolean([])); //true
...
...
...
truthy、falsy值對照表

布林值的隱性轉型:

根據前述,隱性轉型就是透過 JS 自動幫忙轉型,而 if 判斷式的原理,就是當 ( ) 內的值為 true 的時候,就會執行 { } 內的動作。

if(true) {   console.log('因為是 true 才回傳這一行字');}

因此這邊以 if 判斷式舉例,且也可以從回傳的印出結果,證實 if 判斷式在 ( ) 內,確實也能把非布林值的值進行轉換。

以字串為例:
if("a string"){
console.log('顯示這段話的時候,就是字串 "a string" 被轉為 true 了');
} else {
console.log('只有在 "a string" 被判定為 false 的時候,才會顯示這段話');
}
以數字為例:
if(365){
console.log('顯示這段話的時候,就是數字365 被轉為 true 了');
} else {
console.log('只有在數字365 被判定為 false 的時候,才會顯示這段話');
}
以 NaN 為例:
if(NaN){
console.log('顯示這段話的時候,就是 NaN 被轉為 true 了');
} else {
console.log('只有在 NaN 被判定為 false 的時候,才會顯示這段話');
}
if 判斷式的回傳結果
* 除了在 if 判斷式,邏輯運算子也會進行隱性轉型,詳見ㄟ問你喔,邏輯運算子 && 和 || 到底該怎麼用?

二、字串的顯性與隱性轉型

字串的顯性轉型:

字串的顯性轉型一樣是透過函式,這邊將透過回傳結果可觀察到 String() 將數字、布林值、null、undefined 轉為字串。

let a = 666666; 
let b = true;
let c = false;
let d = null;
let e = undefined;
console.log(String(a), typeof String(a)); // 回傳 666666 string console.log(String(b), typeof String(b)); // 回傳 true string
console.log(String(c), typeof String(c)); // 回傳 false string
console.log(String(d), typeof String(d)); // 回傳 null string
console.log(String(e), typeof String(e)); // 回傳 undefined string
console.log(d.toString());
//Uncaught TypeError: Cannot read properties of null (reading 'toString')
console.log(e.toString()); //Uncaught TypeError: Cannot read properties of undefined (reading 'toString')

註:String(value) value.toString() 都是能強制轉型為字串的函式,但在 value.toString() 這個方法中,null 和 undefined 將無法轉為字串型別。

字串的隱性轉型:

字串的隱性轉型,必要的條件是在算式中,至少其中一個值為字串, ( + ) 運算子就會觸發隱性轉型,以下組合都會轉出字串:

  • 字串 + 字串
  • 字串 + 數字
  • 字串 + 布林值
  • 字串 + undefined
  • 字串 + null
  • 字串 + NaN
  • 字串 + 數字 + null
  • 字串 + 物件
  • 字串 + 陣列
let a = "3" + "3"; 
let b = "8" + 3;
let c = "9" + true;
let d = undefined + "3";
let e = null + "3";
let f = NaN + "aaa";
let g = null + 111 + "666";
let h = "here" + {};
let i = "here" + [];
console.log(a, typeof a); // 回傳 33 string
console.log(b, typeof b); // 回傳 83 string
console.log(c, typeof c); // 回傳 9true string
console.log(d, typeof d); // 回傳 undefined3 string
console.log(e, typeof e); // 回傳 null3 string
console.log(f, typeof f); // 回傳 NaNaaa string
console.log(g, typeof g); // 回傳 111666 string
console.log(g, typeof h); // 回傳 here[object Object] string console.log(g, typeof i); // 回傳 here[object Object] string

以上為布林值及字串的強制轉型,而下一篇將專注在整理數字的強制轉型,並比較多在討論比較運算子 ==寬鬆等於、!=寬鬆不等於的強制轉型過程。

參考資料

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

Karen Huang
Karen Huang

Written by Karen Huang

寫下來的,比較不容易忘記。

No responses yet

Write a response