---
type: reference
language: javascript
slug: object/keys
title: "Object.keys() / values() / entries()"
title_tag: "JavaScript Object.keys の使い方 — 値と組も取り出す"
summary: >
  オブジェクトのキー・値・組を配列で取り出します。継承したものや列挙できないものは入りません。
  数字に見えるキーが先に来る理由、配列に戻す方法まで実行して確かめます。
description: >
  鍵・値・組を配列で取り出します。整数に見える鍵が先に来る順序の規則、配列や文字列に使ったときの結果、null を渡すと落ちる点まで実行して確かめます。
status: published
difficulty: 2
minutes: 8

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

sources:
  - title: "Object.keys — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-object.keys"
  - title: "Object.entries — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-object.entries"
  - title: "OrdinaryOwnPropertyKeys — ECMAScript® 2026 Language Specification"
    url: "https://tc39.es/ecma262/#sec-ordinaryownpropertykeys"

terms: [列挙可能, 自身のプロパティ, プロトタイプ]

links:
  related:
    - javascript/how-to/object/merge
    - javascript/errors/is-not-a-function
    - javascript/learn/object/iterate
    - javascript/learn/object/basics
    - javascript/errors/cannot-convert-undefined-or-null

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

オブジェクトの中身を[key:配列として]取り出します。
オブジェクトには `map()` も `filter()` も無いので、**まず配列にします。**

```js run
const scores = { math: 80, english: 95 };

console.log(Object.keys(scores));
console.log(Object.values(scores));
console.log(Object.entries(scores));
```
```output
[ 'math', 'english' ]
[ 80, 95 ]
[ [ 'math', 80 ], [ 'english', 95 ] ]
```

上のコードは書き換えて実行できます。項目を1つ足してみてください。

## 使い分け

| | 返るもの | 使う場面 |
|---|---|---|
| `Object.keys()` | キーの配列 | 名前だけ要る。件数を数える |
| `Object.values()` | 値の配列 | 合計・最大など、値だけ要る |
| `Object.entries()` | `[キー, 値]` の配列 | **両方要る**（いちばん多い） |

```js run
const scores = { math: 80, english: 95, science: 70 };

console.log(Object.keys(scores).length);
console.log(Object.values(scores).reduce((sum, n) => sum + n, 0));

for (const [name, score] of Object.entries(scores)) {
  console.log(`${name}: ${score}`);
}
```
```output
3
245
math: 80
english: 95
science: 70
```

`entries()` は `[キー, 値]` の配列を返すので、**分割代入で受け取る**と読めます。

## 入らないもの

`Object.keys()` が返すのは、[key:そのオブジェクト自身が持つ]、
[key:列挙できる]、[key:文字列の]キーだけです。**3つとも条件です。**

### 受け継いだものは入らない

```js run
const parent = { p: 1 };
const child = Object.create(parent);
child.c = 2;

console.log(Object.keys(child));
console.log('p' in child);
console.log(child.p);
```
```output
[ 'c' ]
true
1
```

`child.p` は[em:読める]のに、`Object.keys()` には[bad:入りません]。
「読めるかどうか」と「自身が持っているか」は別です。

[dim:for...in は受け継いだものも回します。だから配列にも使ってはいけません。]

### 列挙できないものは入らない

```js run
const obj = Object.defineProperty({ a: 1 }, 'b', { value: 2, enumerable: false });

console.log(Object.keys(obj));
console.log(obj.b);
console.log(Object.getOwnPropertyNames(obj));
```
```output
[ 'a' ]
2
[ 'a', 'b' ]
```

隠したいときは `enumerable: false`、全部見たいときは `getOwnPropertyNames()` です。

### Symbol のキーは入らない

```js run
const s = Symbol('id');
const obj = { a: 1, [s]: 2 };

console.log(Object.keys(obj));
console.log(Object.getOwnPropertySymbols(obj).length);
console.log(obj[s]);
```
```output
[ 'a' ]
1
2
```

**`Symbol` は「うっかり列挙されない」ための道具**でもあります。

## 順序

数字に見えるキーが[key:先に]、[num:小さい順]で並びます。そのあとが**書いた順**です。

```js run
const obj = { b: 1, 2: 2, a: 3, 1: 4 };

console.log(Object.keys(obj));
```
```output
[ '1', '2', 'b', 'a' ]
```

`b` より先に `1` と `2` が来ています。**書いた順にはなりません。**

**順序に依存する処理を書かないでください。** 順番が要るなら `Map` か配列を使います。

```js run
const m = new Map([['b', 1], [2, 2], ['a', 3]]);

console.log([...m.keys()]);
```
```output
[ 'b', 2, 'a' ]
```

`Map` は[key:入れた順]を保ちます。キーに数値も使えます。

## 配列や文字列に使うと

**添字が文字列で返ります。** 配列に使う理由はほぼありません。

```js run
console.log(Object.keys([10, 20]));
console.log(Object.keys('abc'));
console.log([...[10, 20].keys()]);
console.log([...[10, 20].entries()]);
```
```output
[ '0', '1' ]
[ '0', '1', '2' ]
[ 0, 1 ]
[ [ 0, 10 ], [ 1, 20 ] ]
```

配列の添字が欲しいなら `array.keys()`（[key:数値]で返る）か `entries()` を使ってください。

## 配列からオブジェクトに戻す

`Object.fromEntries()` が `entries()` の逆です。

```js run
console.log(Object.fromEntries([['a', 1], ['b', 2]]));
console.log(Object.fromEntries(new Map([['a', 1]])));
```
```output
{ a: 1, b: 2 }
{ a: 1 }
```

**「配列にして、加工して、戻す」**が定型です。

```js run
const scores = { math: 80, english: 95, science: 70 };

const passed = Object.fromEntries(
  Object.entries(scores).filter(([, score]) => score >= 80),
);

const doubled = Object.fromEntries(
  Object.entries(scores).map(([name, score]) => [name, score * 2]),
);

console.log(passed);
console.log(doubled);
```
```output
{ math: 80, english: 95 }
{ math: 160, english: 190, science: 140 }
```

オブジェクトに `filter()` や `map()` は無いので、**この形で代わりにします。**

[dim:分割代入で先頭を空けておくのは「1つ目は使わない」という書き方です。読み飛ばす意図が伝わります。]

## null や undefined を渡すと落ちる

```js bad
console.log(Object.keys(null));
```
```output
TypeError: Cannot convert undefined or null to object
```

**通信の結果をそのまま渡すと、ここで落ちます。**

```js run
const data = null;

console.log(Object.keys(data ?? {}));
console.log(Object.keys(data ?? {}).length === 0);
```
```output
[]
true
```

`?? {}` を挟むだけで防げます。

結合と複製の話は
[オブジェクトを結合する](/ja/javascript/how-to/object/merge/) にまとめてあります。

鍵に文字列以外を使いたくなったら、オブジェクトではなく `Map` の出番です。数値の `1` と文字列の `'1'` を別の鍵として持てます。
→ [Map と Set](/ja/javascript/reference/collection/map-set/)
