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

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

參考資料