---
type: how-to
language: javascript
slug: object/empty-check
title: "空かどうかを調べる — 配列・オブジェクト・文字列"
title_tag: "JavaScript で空判定 — 配列・オブジェクト・文字列の調べ方"
summary: >
  空の配列も空のオブジェクトも真なので、if (value) では判定できません。それぞれの正しい
  調べ方、null と空を分けるべき理由、1つの関数にまとめる形まで実行して確かめます。
description: >
  空の配列も空のオブジェクトも if では真になります。長さ・鍵の数・size のどれを見るか、
  null と空を分ける判断、まとめて判定する関数の書き方まで実行して確かめられます。
status: published
difficulty: 1
minutes: 7

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

sources:
  - title: "Object.keys — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-object.keys"
  - title: "ToBoolean — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-toboolean"
  - title: "Object.keys() — MDN"
    url: "https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/keys"

terms: [真偽値変換, 列挙可能, 空]

links:
  related:
    - javascript/reference/object/keys
    - javascript/why/strict-equality
    - javascript/reference/collection/map-set
    - javascript/reference/operator/optional-chaining

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

## 答え

**種類ごとに見るところが違います。**

| 種類 | 調べ方 |
|---|---|
| 配列 | `list.length === 0` |
| 文字列 | `text.length === 0` |
| オブジェクト | `Object.keys(obj).length === 0` |
| `Map` / `Set` | `map.size === 0` |
| `null` / `undefined` | `value == null` |

```js run
console.log([].length === 0);
console.log(''.length === 0);
console.log(Object.keys({}).length === 0);
console.log(new Map().size === 0, new Set().size === 0);
```
```output
true
true
true
true true
```

## `if (value)` では判定できない

**これがいちばんの落とし穴です。**

```js bad
console.log(Boolean([]));
console.log(Boolean({}));
console.log(Boolean(new Map()));
```
```output
true
true
true
```

**空の配列も空のオブジェクトも「真」です。**
オブジェクトはすべて真になり、中身は見られません。

偽になるのは、この6つだけです。

```js run
for (const value of [false, 0, '', null, undefined, NaN]) {
  console.log(JSON.stringify(value), Boolean(value));
}
```
```output
false false
0 false
"" false
null false
undefined false
null false
```

[dim:`NaN` は JSON にすると `null` と書かれます。ここでの最後の行は `NaN` の結果です。]

だから `if (list)` は「配列があるか」しか見ていません。
**中身が空かどうかは、別に調べる必要があります。**

```js run
const list = [];

console.log(list ? 'ある' : 'ない');
console.log(list.length > 0 ? '中身がある' : '空');
```
```output
ある
空
```

## オブジェクトの空判定で気をつけること

`Object.keys()` が数えるのは[key:自分の・列挙できる・文字列の鍵]だけです。

```js run
const withUndefined = { a: undefined };
const inherited = Object.create({ base: 1 });
const symbolOnly = { [Symbol('s')]: 1 };

console.log(Object.keys(withUndefined).length);
console.log(Object.keys(inherited).length);
console.log(Object.keys(symbolOnly).length);
console.log(Object.getOwnPropertySymbols(symbolOnly).length);
```
```output
1
0
0
1
```

- **`undefined` が入っていても、鍵はある**（空ではない）
- 受け継いだ鍵は数えない
- **`Symbol` の鍵は数えない**（あるのに空と判定される）

`JSON.stringify()` で見ると、また違う結果になります。

```js bad
console.log(JSON.stringify({ a: undefined }));
console.log(JSON.stringify({ a: undefined }) === '{}');
```
```output
{}
true
```

**鍵はあるのに `{}` と出ます。**
`JSON.stringify()` での空判定は[bad:結果が変わるので使わないでください]。

→ [Object.keys() / values() / entries()](/ja/javascript/reference/object/keys/)

## `null` と「空」を分ける

**この2つは、たいてい意味が違います。**

| 状態 | 意味 |
|---|---|
| `null` / `undefined` | まだ来ていない・失敗した |
| `[]` / `{}` | **来たが、0件だった** |

画面の出し分けで効いてきます。

```js run
function message(list) {
  if (list == null) return '読み込み中';
  if (list.length === 0) return '該当なし';
  return `${list.length}件`;
}

console.log(message(null));
console.log(message([]));
console.log(message([1, 2]));
```
```output
読み込み中
該当なし
2件
```

**この3つを1つにまとめると、読み手に嘘をつくことになります。**
「読み込み中」と「0件」は、利用者にとって全く違う情報です。

[dim:分ける必要が無い場面もあります。そのときは `list?.length` を見れば、`null` も空も一度に扱えます。]

## まとめて判定する

種類が混ざるものを受けるなら、1つの関数にします。

```js run
function isEmpty(value) {
  if (value == null) return true;
  if (typeof value === 'string' || Array.isArray(value)) return value.length === 0;
  if (value instanceof Map || value instanceof Set) return value.size === 0;
  if (typeof value === 'object') return Object.keys(value).length === 0;
  return false;
}

for (const value of [null, undefined, '', [], {}, new Map(), 0, [1], { a: 1 }]) {
  console.log(isEmpty(value), '|', Array.isArray(value) ? JSON.stringify(value) : String(value));
}
```
```output
true | null
true | undefined
true | 
true | []
true | [object Object]
true | [object Map]
false | 0
false | [1]
false | [object Object]
```

**`0` と `false` は「空」ではありません。** 値として入っています。
[bad:ここを空に含めると、0件と0という値を区別できなくなります。]

## 空に倒すときの `??` と `||`

**無いものを空配列にして進める書き方は便利ですが、演算子で結果が変わります。**

```js run
for (const value of [null, undefined, [], 0, '']) {
  console.log(
    JSON.stringify(value),
    '| ?? ->',
    JSON.stringify(value ?? []),
    '| || ->',
    JSON.stringify(value || []),
  );
}
```
```output
null | ?? -> [] | || -> []
undefined | ?? -> [] | || -> []
[] | ?? -> [] | || -> []
0 | ?? -> 0 | || -> []
"" | ?? -> "" | || -> []
```

配列を扱うだけなら差は出ませんが、**`0` や空文字が混ざる場所では変わります。**
[key:「無い」を空に倒すなら `??`]です。
→ [?. と ??](/ja/javascript/reference/operator/optional-chaining/)

## 穴だけの配列は「空」ではない

```js bad
const holed = [, ,];

console.log(holed.length);
console.log(holed.filter(() => true).length);
console.log(Object.keys(holed).length);
```
```output
2
0
0
```

`length` は2ですが、**要素は1つもありません。**
`length` だけで判定すると、[bad:空なのに空でないと出ます]。

穴が混ざりうるなら、`Object.keys(list).length` を見てください。
→ [Array.from() / Array.of() / new Array()](/ja/javascript/reference/array/from/)

## 入力欄の未入力をまとめて挙げる

```js run
const form = { name: '', tags: [], note: null, count: 0 };

const missing = Object.entries(form)
  .filter(([, value]) =>
    value == null ||
    (typeof value === 'string' && value.trim() === '') ||
    (Array.isArray(value) && value.length === 0),
  )
  .map(([key]) => key);

console.log(missing);
```
```output
[ 'name', 'tags', 'note' ]
```

**`count: 0` は未入力に含めていません。**
`0` は入力された値です。ここを混ぜると、[bad:0 を入れた人に「未入力です」と言うこと]になります。

## 空白だけの文字列

```js bad
const input = '   ';

console.log(input.length === 0);
console.log(input.trim().length === 0);
```
```output
false
true
```

入力欄の値を見るときは、**`trim()` してから**長さを見てください。
→ [trim() / padStart() / padEnd() / repeat()](/ja/javascript/reference/string/trim-pad/)

## まとめ

- **`if (value)` では空を判定できない。** 空の配列もオブジェクトも真
- 配列と文字列は `length`、オブジェクトは `Object.keys().length`、`Map` / `Set` は `size`
- `Object.keys()` は[bad:Symbol の鍵を数えない]
- **`JSON.stringify()` で空判定をしない**。`undefined` の鍵が消える
- `null`（来ていない）と `[]`（0件）は**分けて扱う**
- 空に倒すなら `||` ではなく `??`
- **穴だけの配列は `length` が0にならない**
- 入力欄は `trim()` してから長さを見る。**`0` を未入力に含めない**
