JavaScript:値と型(バグを減らす型感覚)
音声
目次
number / string / boolean / null / undefined
基本的な値の種類を見分けて、型による振る舞いの違いでバグを減らせるようにしましょう。
number(数値)は計算に使い、string(文字列)はテキスト、boolean(真偽)は条件分岐に使います。
nullは「値がないことを明示」し、undefinedは「値が未定義または未設定」を表します。これらが混ざると思わぬ挙動になるため、使い分けが重要です。
この最小例は、ボタンを押すと typeof の結果をまとめて表示し、
「数値のゼロ」と「文字列のゼロ」が別物であること、null と undefined の違いを目で確認できるようにするデモです。
貼り付け場所:CodePenを想定する場合はHTML欄とJS欄に分けて貼り付けます。HTML欄にはボタンと出力要素(例:#check, #result)を用意します。
<!-- HTML欄(CodePenのHTMLエリアに貼ってください) -->
<button id="check">型チェック実行</button>
<div id="result"></div>
最小コード:
// JS欄(CodePenのJSエリアに貼ってください)
const out = document.getElementById('result');
document.getElementById('check').addEventListener('click', () => {
const a = 0; // number
const b = "0"; // string
const c = null; // null
const d = undefined; // undefined
out.innerText = [
`a:${a} (${typeof a})`,
`b:${b} (${typeof b})`,
`c:${c} (${typeof c})`,
`d:${d} (${typeof d})`,
].join('\n');
});
確認方法:ボタンを押して、表示が次のようになればOKです。特に null が object と表示される点は、JavaScriptの仕様として覚えておくと混乱が減ります。
実行結果:
a:0 (number)
b:0 (string)
c:null (object)
d:undefined (undefined)
結果の説明:
1つ目。a は数値のゼロなので、typeof a は number になります。数値は足し算などの計算に使われます。
2つ目。b は文字列のゼロなので、typeof b は string になります。見た目が同じ「0」でも、文字列は計算ではなくテキストとして扱われます。
3つ目。c は null なので、本来は「値がないことを明示」という意味です。ただしJavaScriptの歴史的な理由で、typeof null は object と表示されます(これは例外として覚えておくのが安全です)。
4つ目。d は undefined なので、typeof d は undefined になります。これは「値が未設定・未定義」の状態を表します。
まとめると、見た目が似ていても型が違うと扱いが変わるので、typeof で確認できるようにしておくとバグを減らせます。
等価比較:== と === の違い
==(ダブルイコール)は型変換を行った上で比較し、===(トリプルイコール)は型も値も同じ場合にのみ真になります。
例えば 0 == "0" は真になりますが、0 === "0" は偽になります。
条件分岐では型の違いで誤判定しやすいため、原則 === を使うことで予測可能性が高まります。
既存コードで意図的な型変換がある場合に限り == を選ぶ判断が必要です。
暗黙の型変換で起きる事故例
暗黙の型変換(coercion)は便利ですが、意図しない結果を生みます。
例:プラスは「文字列連結」になりやすく、マイナスは「数値計算」になりやすいです。
"" + 1 // "1"
"" - 1 // -1
また、直感に反する比較が起こることがあります。
[] == 0 // true
文字列連結や数値計算を行うときは、明示的な変換(Number() / String())を使うと事故が減ります。
明示的な変換の例:
// 数値にする
Number("10") // 10
Number("") // 0
Number("abc") // NaN(数値にできない)
// 文字列にする
String(10) // "10"
String(null) // "null"
よくある安全な書き方(足し算を必ず数値にする):
const a = "10";
const b = "2";
const sum = Number(a) + Number(b); // 12
入力値(フォームなど)は基本文字列なので、計算前に数値へ変換し、必要なら Number.isNaN() でチェックします。
NaNとInfinityの扱い
計算で想定外の値になることがあります。0/0 は NaN(Not-a-Number)になり、1/0 は Infinity になります。 NaN は自分自身とも等しくない特徴があり、NaN === NaN は偽です。 isNaN() や Number.isNaN()、Number.isFinite() を使って検査し、無効な計算結果を早めに処理すると安全性が高まります。
最小の実例:
const x = 0 / 0; // NaN
const y = 1 / 0; // Infinity
const z = Number("abc"); // NaN
// isNaN は「数値に変換してから」判定するので、文字列でも true になり得る
console.log(isNaN("abc")); // true
// Number.isNaN は「本当に NaN か」だけを見る(より安全)
console.log(Number.isNaN(z)); // true
console.log(Number.isNaN("abc")); // false
// 有限かどうか(NaN と Infinity をまとめて弾ける)
console.log(Number.isFinite(x)); // false
console.log(Number.isFinite(y)); // false
console.log(Number.isFinite(123)); // true
// 無効な計算結果を早めに処理する例
function safeDiv(a, b) {
const r = a / b;
if (!Number.isFinite(r)) return 0; // NaN / Infinity をまとめて回避
return r;
}
console.log(safeDiv(10, 2)); // 5
console.log(safeDiv(1, 0)); // 0
console.log(safeDiv(0, 0)); // 0
型を確認する(typeofの基本)
目次 1 では「型の違いを目で確認する」体験をしました。ここでは実務で使うために、
typeof を「いつ」「どう使うか」と、例外(null・配列)だけ押さえます。
基本:値が何っぽいかを手早く知りたいときに typeof を使います。
typeof 123 // "number"
typeof "a" // "string"
typeof true // "boolean"
typeof undefined // "undefined"
注意1(null):typeof null は歴史的事情で "object" になります。
なので null 判定は x === null のように値比較で行うのが確実です。
const x = null;
console.log(typeof x); // "object"(例外)
console.log(x === null); // true(これが確実)
注意2(配列):配列も typeof だと "object" になります。
配列かどうかは Array.isArray() を使います。
const a = [1, 2, 3];
console.log(typeof a); // "object"
console.log(Array.isArray(a)); // true
よくある使い方:関数の引数が想定どおりかを早めにチェックして、変な値なら止めます。 これだけで「後半で謎のエラーになる」事故が減ります。
function addSafe(n) {
if (typeof n !== "number") return 0; // 早めに回避
return n + 1;
}
console.log(addSafe(10)); // 11
console.log(addSafe("10")); // 0
実行方法:ブラウザで開くか、CodePenのRunで実行します。Consoleで結果を見ます。
確認方法:console.logの出力が想定どおりかを確認します。
よくあるミス:Consoleを開いていないため出力が見えない、または変数名のスペル違いでReferenceErrorになることがあります。
注意(ここだけ)
typeof nullは歴史的事情で"object"になります(null判定はvalue === nullを使います)。NaNは「自分自身とも等しくない」のでvalue === NaNは常にfalseです。判定はNumber.isNaN(value)を使います。小数は誤差が出ます(例:
0.1 + 0.2 !== 0.3)。金額などは「整数(円・最小単位)」で扱うのが安全です。
要約
- number/string/boolean/null/undefined は用途ごとに使い分けるとバグが減ります。
- === は型も比較するため予測可能で、原則こちらを使います。
- 暗黙の型変換は直感と異なる結果を生むため明示変換を検討します。
- NaN は自分自身と等しくないため Number.isNaN での検査が有効です。
- typeof は基本を押さえつつ null や配列の扱いを補助関数で補うと安全です。