---
type: why
language: javascript
slug: typeof-null
title: "なぜ typeof null は \"object\" なのか"
title_tag: "なぜ typeof null は object なのか — 正しい判定方法"
summary: >
  仕様がそう定めているからです。理由は仕様に書かれていません。null を見分ける正しい方法、
  undefined との使い分け、Object.prototype.toString による型の調べ方までを実行して確かめます。
description: >
  typeof では null を見分けられません。=== null と == null の使い分け、typeof が
  object を返すものの一覧、既定値が null では働かない理由まで実行して確かめられます。
status: published
difficulty: 2
minutes: 8

versions:
  verified: "Node 22.22.3"
  since: "ES1"
  deprecated: null
  removed: null

sources:
  - title: "The typeof Operator — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-typeof-operator"
  - title: "Object.prototype.toString — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-object.prototype.tostring"
  - title: "typeof — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/typeof"

terms: ["typeof", "null", "undefined", 型判定]

links:
  related:
    - javascript/why/strict-equality
    - javascript/errors/cannot-read-properties-of-undefined
    - javascript/learn/object/basics

content_updated_at: 2026-09-08
published_at: 2026-09-08
---

**仕様がそう決めているからです。**

`typeof` の結果は仕様の表で決まっており、`Null` には `"object"` と書かれています。
**理由は仕様に書かれていません。**

```js run
console.log(typeof null);
console.log(typeof undefined);
console.log(null === undefined);
```
```output
object
undefined
false
```

[dim:古い実装の値の持ち方に由来する、という経緯が広く知られています。ただし仕様はその理由を述べていないので、ここでは「そう決まっている」以上のことは書きません。直そうという提案は、既存のコードを壊すため採用されていません。]

## 何が困るのか

**`typeof` でオブジェクトを判定すると、`null` が紛れ込みます。**

```js bad
function isObject(value) {
  return typeof value === 'object';
}

console.log(isObject({}));
console.log(isObject(null));
```
```output
true
true
```

このあと `value.name` を読めば落ちます。
→ [Cannot read properties of undefined](/ja/javascript/errors/cannot-read-properties-of-undefined/)

`null` を外せば直ります。

```js run
function isObject(value) {
  return typeof value === 'object' && value !== null;
}

console.log(isObject({}));
console.log(isObject(null));
console.log(isObject([]));
```
```output
true
false
true
```

[bad:配列も `true` になります。] `typeof` は配列を区別しません。
配列かどうかは `Array.isArray()` で見てください。

## `typeof` が `"object"` を返すもの

```js run
for (const value of [null, {}, [], new Date(0), /x/]) {
  console.log(typeof value, '|', Object.prototype.toString.call(value));
}
```
```output
object | [object Null]
object | [object Object]
object | [object Array]
object | [object Date]
object | [object RegExp]
```

**`typeof` は5つとも同じ答えを返します。**
`Object.prototype.toString.call()` なら区別できます。

| 調べたいこと | 使うもの |
|---|---|
| `null` か | `value === null` |
| `null` か `undefined` か | `value == null` |
| 配列か | `Array.isArray(value)` |
| 素のオブジェクトか | `typeof v === 'object' && v !== null && !Array.isArray(v)` |
| 細かい種類 | `Object.prototype.toString.call(value)` |

## `null` の見分け方

```js run
const values = [null, undefined, {}, [], 0];

console.log(values.map((v) => v === null));
console.log(values.map((v) => v == null));
```
```output
[ true, false, false, false, false ]
[ true, true, false, false, false ]
```

- `=== null` … **`null` だけ**
- `== null` … `null` と `undefined` の両方

`==` を使ってよいのはこの場面だけです。
→ [なぜ == ではなく === を使うのか](/ja/javascript/why/strict-equality/)

## `null` と `undefined` は役割が違う

```js run
console.log(JSON.stringify({ a: null, b: undefined }));

const withDefault = (x = '既定') => x;

console.log(withDefault(undefined));
console.log(withDefault(null));
```
```output
{"a":null}
既定
null
```

- `undefined` … **まだ何も入っていない**。処理系が付ける
- `null` … **意図的に「無い」と入れた**。人が付ける

だから既定値は `undefined` のときだけ働きます。
**`null` は「値として入っている」ので、置き換えられません。**

計算に使うと、さらに違いが出ます。

```js run
console.log(null + 1);
console.log(undefined + 1);
```
```output
1
NaN
```

`null` は[num:0]として扱われ、`undefined` は `NaN` になります。
[bad:どちらも「無い」つもりで足すと、結果が変わります。]

## `typeof` が返すのは8種類だけ

```js run
const kinds = new Set(
  [undefined, null, 0, 'a', true, 1n, Symbol('s'), () => {}].map((v) => typeof v),
);

console.log([...kinds].sort());
console.log([...kinds].length);
```
```output
[ 'bigint', 'boolean', 'function', 'number', 'object', 'string', 'symbol', 'undefined' ]
8
```

`{}` も `[]` も `new Date()` も、**全部 `"object"` に潰されます。**
クラスや組み込みの `Array` は `"function"` です。

```js run
console.log(typeof class {});
console.log(typeof Array);
```
```output
function
function
```

## 素のオブジェクトかを見る

```js run
function isPlainObject(value) {
  return typeof value === 'object' && value !== null && !Array.isArray(value);
}

console.log([{}, [], null, new Date(0), 'a'].map(isPlainObject));
```
```output
[ true, false, false, true, false ]
```

[bad:`Date` が `true` になっています。] この書き方は「配列でないオブジェクト」までしか見ません。

**そこまで厳密に見たい場面は多くありません。**
必要なら `Object.prototype.toString.call(value) === '[object Object]'` を使ってください。

## 等価と比較で規則が違う

```js run
console.log(null == 0);
console.log(null >= 0);
console.log(null > 0);
```
```output
false
true
false
```

**`null == 0` は偽なのに、`null >= 0` は真です。**

`==` は `null` を特別扱いして「`undefined` としか等しくない」と決めていますが、
`>=` は[key:数値に変換してから]比べます。`null` は[num:0]になります。

[bad:「等しくないのに、以上ではある」という結果になります。]
`null` を数の比較に混ぜないでください。

## よくある誤解

### 「`typeof` があれば型は分かる」

分かりません。`typeof` が返すのは[num:8]種類だけで、
**オブジェクトの中身は全部 `"object"`** です。

### 「`null` は `typeof` で判定できないから使えない子」

そうではありません。`=== null` で正確に判定できます。
**判定できないのは `typeof` だけ**です。

### 「`null` を返しておけば安全」

呼び出し側が `null` を想定していなければ、そこで落ちます。
**「無い」を返すなら、無いことが起きうると呼び出し側に伝わる形**
（型・命名・書類）**にしてください。**

## 自分で確かめる

上のコードは書き換えて実行できます。

1. `typeof function(){}` を試す（`"object"` ではない）
2. `Object.prototype.toString.call(null)` と `String(null)` を並べる
3. `null == 0` と `null >= 0` を並べる（等価と比較で規則が違う）

**予想してから実行してください。**

## まとめ

- **仕様がそう決めている。** 理由は仕様に書かれていない
- `typeof value === 'object'` は[bad:`null` も通す]。`&& value !== null` を足す
- 配列も `"object"`。配列かどうかは `Array.isArray()`
- `null` だけなら `=== null`、`undefined` も含めるなら `== null`
- **`undefined` は処理系が付け、`null` は人が付ける**
- 既定値は `undefined` のときだけ働く。`null` では働かない
