【実務・中級編】 typeof null が object を返す仕様 – JavaScript実践ガイド

JavaScriptの「typeof null === ‘object’」という歴史的過ちと、僕らが明日から取るべき正しい距離感

現場でコードを書いていて、一度は「なんだこれ?」と首を傾げたことがあるはずだ。
`typeof null` を叩いてみたとき、返ってくるのは `’null’` ではなく `’object’`。

「JavaScriptって、やっぱりどこか壊れてるよね」

そう笑うのは簡単だ。だが、我々フロントエンド・スペシャリストは、その「壊れた仕様」を単なるバグとして片付けるのではなく、言語の歴史的背景として飲み込み、いかにスマートに回避して設計に落とし込むかという「術」を持っておく必要がある。今日は、この泥臭いJavaScriptの仕様と、現場で二度とバグを生ませないための知見を共有しよう。

—

なぜ `null` は `object` なのか?(あるいは、歴史の罪)

この挙動は、JavaScriptが誕生した1995年当時、Brendan Eichがわずか10日で言語のプロトタイプを書き上げた時代の「負の遺産」だ。

当時のJavaScriptのデータ型は、CPUレベルの表現として「型タグ(Type Tag)」を使って管理されていた。具体的には、値のメモリ上の表現の下位3ビットを見て型を判定していたのだが、当時の実装では以下のルールだった。

  • `000`: オブジェクト(Object)
  • `001`: 整数(Integer)
  • `010`: ダブル型(Double)
  • `100`: 文字列(String)
  • `110`: ブール型(Boolean)

そして、`null` はメモリ上で「全てが0(マシン語のNULLポインタ)」として表現されていた。そのため、判定ロジックが「下位3ビットが0だから、これはオブジェクトだね」と誤判定してしまったのだ。

この仕様を修正しようという動きは過去に一度あった。しかし、ECMAScriptの策定委員会(TC39)が「それを直すと、世の中の既存のWebサイトがすべて壊れる」と判断し、「直さないこと」を仕様として確定させた。つまり、これはバグではなく「仕様」として我々が一生付き合っていくべき運命なのだ。

—

実務で「絶対にやってはいけない」判定と、その代案

現場で最もやりがちなミスは、単に `typeof` に頼り切ることだ。

// 【危険】nullをオブジェクトとして扱ってしまう例
const data = null;

if (typeof data === ‘object’) {
// dataがnullなのにここに入ってしまう!
// data.id にアクセスした瞬間に「Cannot read property ‘id’ of null」で爆発する
console.log(‘データはオブジェクトです’);
}

この「爆弾」を避けるために、僕らが実務で採用すべき、最も堅牢でモダンなアプローチをいくつか紹介しよう。

1. 厳密なnullチェック(基本形)

単純だが、これが最強だ。`typeof` は使わず、値そのものを評価する。

const value = null;

// null かどうかを判定するなら、厳密等価演算子を使うのがベスト
if (value === null) {
console.log(‘値はnullです’);
}

2. オブジェクトのみを判定したい場合

「nullではない、純粋なオブジェクトだけを扱いたい」というケースは非常に多い。そんな時はこう書く。

/

  • 厳密に「null以外のオブジェクト」を判定するユーティリティ

/
function isObject(val) {
// typeof val === ‘object’ だけだと null も true になるため、
// val !== null を条件に加えるのが鉄則
return val !== null && typeof val === ‘object’;
}

console.log(isObject({ a: 1 })); // true
console.log(isObject(null)); // false (ここで守られる)
console.log(isObject([])); // true (配列もJSではobjectなので注意)

3. TypeScriptを使っているなら

もしTypeScript環境であれば、そもそも「なぜそんな型が混入したのか」という設計の問題になることが多いが、防御的プログラミングとしては「ユーザー定義型ガード」を活用しよう。

// 型ガード関数を使って、安全にオブジェクトを扱う
function isObject(val: unknown): val is Record {
return typeof val === ‘object’ && val !== null;
}

const input: unknown = fetchData();

if (isObject(input)) {
// このブロックの中では、inputは安全にオブジェクトとして扱える
console.log(input.someKey);
}

—

プロとしての結論:仕様を「知っている」ことと「制御できる」こと

JavaScriptの歴史的な仕様を理解することは、単なる知識の蓄積ではない。「なぜブラウザはこういう挙動をするのか」という背景を知っているだけで、デバッグのスピードが劇的に変わる。

「`typeof null` が `object` である」という事実は、これからも変わらない。
しかし、それを「JavaScriptの汚点だ」と嘆くのではなく、「nullを除外する条件式を常にセットで書く」という習慣をチームの文化に定着させること。 それこそが、シニアエンジニアとしてチームのコード品質を底上げするための唯一の解だ。

明日のコードレビューで、もし `typeof` だけで null を弾こうとしているメンバーがいたら、ぜひこの知見をシェアしてあげてほしい。「なぜそうなるのか」という理由を添えて伝えれば、そのメンバーの視座も一段階上がるはずだ。

泥臭い仕様と仲良くやっていこう。それが、このWebという広大な海を航海するフロントエンド・スペシャリストの嗜みだ。

コメント

タイトルとURLをコピーしました