JavaScript 型変換 完全ガイド
JavaScript を扱っていると、 "5" + 1 が "51" になったり、 "5" - 1 が 4 になったりする状況に出くわします。最初は混乱するかもしれませんが、これは JavaScript の型変換(Type Conversion)メカニズムによるものです。
型変換とは、あるデータ型を別の型へ変換するプロセスを指します。JavaScript は動的型付け言語なので、開発者が明確に型を指定しなくても、ランタイム時に自動的に型が決定・変換されます。このような特性は開発を便利にしますが、予期せぬバグの原因にもなり得ます。
この投稿では、明示的な型変換と暗黙的な型変換の違いから、オブジェクトの型変換、そして実務で注意すべき落とし穴まで、JavaScript の型変換のあらゆる側面を扱います。このガイドを通じて型変換の動作原理を正確に理解し、より安全で予測可能なコードを書けるようになりましょう。
明示的型変換 vs 暗黙的型変換
JavaScript の型変換は大きく二つに分けられます。
明示的型変換(Explicit Type Conversion) は、開発者が意図を持って明確に型を変換することです。String(), Number(), Boolean() といった関数を使って型をはっきり変えます。
暗黙的型変換(Implicit Type Conversion/Type Coercion) は、JavaScript エンジンが自動的に型変換を行うことです。演算子や関数が期待する型と異なる値を受け取った際に、暗に変換が行われます。
// 明示的型変換
const num = Number("123"); // 文字列 → 数字
// 暗黙的型変換
const result = "5" + 1; // "51"(数字 1 が文字列に変換される)
明示的型変換はコードの意図を明確に示すため、可読性と保守性が高まります。対して暗黙的型変換は便利ではありますが、予期しない結果を招く可能性があります。
明示的型変換の手法
文字列に変換する
文字列に変換する方法は三つあります。
String() 関数を使う
String() 関数はどんな値でも文字列に変換します。
String(123); // "123"
String(true); // "true"
String(null); // "null"
String(undefined); // "undefined"
.toString() メソッドを使う
ほとんどの値は .toString() メソッドを持っています。しかし、null と undefined はこのメソッドを持たないため、エラーになります。
(123).toString(); // "123"
true.toString(); // "true"
[1, 2, 3].toString(); // "1,2,3"
// null と undefined はエラー
// null.toString(); // TypeError
空文字列と連結する
空文字列("")と + 演算子を使うと、簡単に文字列に変換できます。
123 + ""; // "123"
true + ""; // "true"
null + ""; // "null"
数字に変換する
数字に変換する方法もいくつかあります。
Number() 関数を使う
Number() 関数は文字列やブール値を数字に変換します。変換できない値は NaN(Not a Number)を返します。
Number("123"); // 123
Number("123abc"); // NaN
Number(true); // 1
Number(false); // 0
Number(null); // 0
Number(undefined); // NaN
Number(" 123 "); // 123(前後の空白を除去)
parseInt() と parseFloat() を使う
parseInt() と parseFloat() は文字列の先頭から数字をパースします。数字でない文字が出てきたら、その直前までを変換します。
parseInt("123", 10); // 123
parseInt("123px", 10); // 123("px" は無視される)
parseInt("abc123", 10); // NaN(数字で始まっていない)
parseFloat("3.14"); // 3.14
parseFloat("3.14.15"); // 3.14(最初のドットまで)
parseInt() の第二引数は基数(radix)を示します。10進数に変換する際には 10 を明示するのが安全です。
単項プラス演算子
単項 + 演算子は、値を数字に素早く変換する手段です。
+"123"; // 123
+"10"; // 10
+true; // 1
+false; // 0
+"abc"; // NaN
ブールに変換する
Boolean() 関数を使う
Boolean() 関数は値をブールに変換します。
Boolean(1); // true
Boolean(0); // false
Boolean("hello"); // true
Boolean(""); // false
Boolean([]); // true(空配列も truthy)
Boolean({}); // true(空オブジェクトも truthy)
Falsy 値 vs Truthy 値
JavaScript には false に変換される特別な値があります。これを falsy 値 と呼びます。
Falsy 値(合計 8 つ):
false0-00n(BigInt の 0)NaN""(空文字列)nullundefined
それ以外のすべての値は truthy 値 となります。注意すべきは、次のような値も truthy であるということです:
Boolean("false"); // true(文字列 "false")
Boolean("0"); // true(文字列 "0")
Boolean([]); // true(空配列)
Boolean({}); // true(空オブジェクト)
Boolean(" "); // true(空白文字)
Boolean(function(){}); // true(関数)
暗黙的型変換のさまざまな状況
文字列コンテキスト
+ 演算子でオペランドのいずれかが文字列であれば、もう片方も文字列に変換されます。
"5" + 1; // "51"
1 + "5"; // "15"
"Hello" + true; // "Hellotrue"
"Result: " + 100;// "Result: 100"
しかし複数の値を加算する場合、順序が重要です:
1 + 2 + "3"; // "33"(1+2=3、3+"3"="33")
"1" + 2 + 3; // "123"("1"+2="12"、"12"+3="123")
数字コンテキスト
+ を除く算術演算子(-, *, /, %)はオペランドを数字に変換します。
"5" - 1; // 4
"5" * "2"; // 10
"5" / 2; // 2.5
"5" % 2; // 1
"10" - "3"; // 7
変換できない例外的な場合 NaN になります:
"abc" - 1; // NaN
"5" * "abc"; // NaN
ブールコンテキスト
条件文(if, else)では値が自動的にブールに変換されます。
if ("") {
console.log("空文字列"); // 実行されない
}
if ("Hello") {
console.log("文字あり"); // ✅ 実行される
}
if (0) {
console.log("0"); // 実行されない
}
if ([]) {
console.log("配列"); // ✅ 実行される(空配列は truthy)
}
論理演算子(&&, ||, !)もブールコンテキストを作ります:
!!"hello"; // true
!!0; // false
"text" && 5; // 5(最初が truthy なら二番目を返す)
0 || "default"; // "default"(最初が falsy なら二番目を返す)
緩やかな等価比較(==)
== 演算子は型が異なる場合、暗黙的型変換を行います。
"5" == 5; // true(文字列 "5" が数字 5 に変換される)
"0" == false; // true(どちらも 0 に変換される)
0 == ""; // true(空文字列が 0 に変換される)
null == undefined; // true(特別なケース)
null == 0; // false(null は 0 に変換されない)
このような予期せぬ動作を避けるために、== の代わりに 厳密な等価比較演算子 === を使用することが推奨されます。
"5" === 5; // false
"0" === false; // false
0 === ""; // false
オブジェクトと型変換
オブジェクトが原始値(プリミティブ)へ変換されるとき、JavaScript は特別なメソッドを使用します。
toString() と valueOf() メソッド
オブジェクトが文字列や数字に変換される時、JavaScript は次の順序でメソッドを呼び出します:
- 文字列コンテキスト:
toString()→valueOf() - 数字コンテキスト:
valueOf()→toString()
const obj = {
toString() {return "オブジェクト";
},
valueOf() {return 42;
}
};
String(obj); // "オブジェクト"(toString が呼ばれる)
Number(obj); // 42(valueOf が呼ばれる)
obj + ""; // "オブジェクト"(文字列コンテキスト)
obj - 0; // 42(数字コンテキスト)
配列とオブジェクトの基本的な変換動作:
String([1, 2, 3]); // "1,2,3"
String({}); // "[object Object]"
Number([]); // 0(空配列は 0)
Number([5]); // 5(要素が一つならその値)
Number([1, 2]); // NaN(要素が複数ある)
JSON.stringify() と JSON.parse()
JSON 形式への変換では専用メソッドが使われます。
// オブジェクト → JSON 文字列
JSON.stringify({ a: 1, b: 2 }); // '{"a":1,"b":2}'
// JSON 文字列 → オブジェクト
JSON.parse('{"a":1,"b":2}'); // { a: 1, b: 2 }
| 関数 | 役割 |
|---|---|
JSON.stringify() |
オブジェクト → JSON 文字列 |
JSON.parse() |
JSON 文字列 → オブジェクト |
Date オブジェクトの変換
Date オブジェクトは状況によって異なった変換をします。
const date = new Date("2025-10-22");
// 数字に変換(タイムスタンプ)
Number(date); // 1729544400000
// 文字列に変換
String(date); // "Wed Oct 22 2025 00:00:00 GMT+0"
ぜひこのガイドを参考に、JavaScript の型変換を正しく理解し、より安全で予測可能なコーディングを目指してください。