1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

typeof nullが'object'になる、というJavaScriptの有名な仕様

1
Posted at

「値がオブジェクトかどうかをtypeofで調べればいい」と考えて、こんなコードを書いたことはありませんか(以前扱った「配列やオブジェクトのif文でのtruthy判定」とは違い、今回はtypeof演算子自体の型分類が題材です)。

function processUser(user) {
  if (typeof user === 'object') {
    console.log("処理:", user.name);
  } else {
    console.log("userはオブジェクトではありません");
  }
}

processUser(null);

これを実行すると、TypeError: Cannot read properties of null (reading 'name')というエラーになります。nullは「何もない」ことを表す値のはずなのに、なぜif (typeof user === 'object')の条件に引っかかってしまうのでしょうか。実際にNode.jsで検証しながら確認します。

原因: typeof nullは'object'を返す

console.log(typeof null); // 'object'

これはJavaScript自体の有名な仕様(というより、初期実装のバグがそのまま仕様として固定されたもの)です。typeof演算子は、値の種類を判定するために内部的な型のタグを見ていますが、nullを表す内部タグが偶然にもオブジェクト用のタグと同じ値になっていたことが原因とされています。この挙動は互換性のため、今から直すと世の中の大量のコードが壊れてしまうため、そのまま維持され続けています。

他の値のtypeof結果と並べて見ると、nullだけが直感に反していることが分かります。

console.log(typeof undefined);   // 'undefined'
console.log(typeof {});          // 'object'
console.log(typeof []);          // 'object'(配列もobject扱い)
console.log(typeof 'str');       // 'string'
console.log(typeof 123);         // 'number'
console.log(typeof true);        // 'boolean'
console.log(typeof function(){}); // 'function'

undefinedはちゃんと'undefined'と返ってくるのに、nullだけ'object'になる——ここが誤解を生みやすいポイントです。

正しく判定する方法

「本当にオブジェクトかどうか」を判定したい場合は、nullを明示的に除外します。

function processUserSafe(user) {
  if (user !== null && typeof user === 'object') {
    console.log("処理:", user.name);
  } else {
    console.log("userはオブジェクトではない、またはnullです");
  }
}

processUserSafe(null);           // userはオブジェクトではない、またはnullです
processUserSafe({name: "Alice"}); // 処理: Alice

user !== nullを先に確認してからtypeofをチェックすることで、nullをオブジェクト扱いしてしまう事故を防げます。

おまけ: 配列とオブジェクトの区別にもtypeofは使えない

typeofには、もう1つ紛らわしい点があります。配列もtypeofでは'object'と判定されるため、「オブジェクトなのか配列なのか」をtypeofだけで区別することはできません。

console.log(typeof []); // 'object'
console.log(typeof {}); // 'object'(同じ結果になってしまう)

配列かどうかを正確に判定したい場合は、専用のメソッドを使います。

console.log(Array.isArray([])); // true
console.log(Array.isArray({})); // false

instanceof([] instanceof Array)でも判定できますが、Array.isArray()の方が、複数の実行環境(iframeなど)をまたぐ場合でも正しく判定できるため、実務ではこちらが推奨されています。

まとめ

  • typeof nullは'object'を返す(JS初期実装のバグがそのまま仕様として残っている)
  • typeofだけで「本物のオブジェクトかどうか」を判定すると、nullを誤って通してしまう
  • nullを除外したいときはuser !== null && typeof user === 'object'のように明示的にチェックする
  • 配列かどうかを判定したいときはtypeofではなくArray.isArray()を使う

AIが生成したnullチェックのコードでも、typeofだけに頼った判定を見かけることがあります。typeof ... === 'object'という条件式を見かけたら、nullが紛れ込んでいないか一度確認してみてください。


未経験者向けの講座を運営しています

未経験から Next.js + Supabase + Claude Code で Webアプリを公開するまで を、全24セッションで体系化した教材です。Claude Code を学習パートナーにする CLAUDE.md と学習モード(learner / developer)の設計までセットで含みます。

※ 中上級者には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?