JavaScriptのプログラミングにおいて、オブジェクト(Object)の操作は避けて通ることのできない重要な要素です。
特にオブジェクトが保持するプロパティの一覧を取得し、それをもとにループ処理やデータの加工を行う場面は多岐にわたります。
モダンなJavaScript開発において、オブジェクトのキーを配列として抽出するObject.keysメソッドは、最も基本的かつ強力なツールのひとつです。
本記事では、Object.keysの基本的な使い方から、実務で役立つ応用パターン、さらには他の反復処理メソッドとの違いについて詳しく解説します。
Object.keysの基本的な使い方と仕様
Object.keysは、引数に指定したオブジェクトが持つ「自身で定義された列挙可能なプロパティ名」を配列として返す静的メソッドです。
このメソッドを利用することで、オブジェクトの構造を動的に解析したり、キーの数を確認したりすることが容易になります。
まずは、最もシンプルなコード例を見てみましょう。
// シンプルなユーザーオブジェクトの定義
const user = {
id: 1,
name: "田中太郎",
email: "tanaka@example.com",
role: "admin"
};
// オブジェクトのキーを取得
const keys = Object.keys(user);
console.log(keys);
[ "id", "name", "email", "role" ]
上記の例では、userオブジェクトに含まれる4つのキーが、文字列の配列として抽出されていることがわかります。
ここで重要なのは、返り値が「配列(Array)」であるという点です。
配列として取得できるため、JavaScriptの強力な配列メソッドであるforEachやmap、filterなどをそのままチェーンして利用できます。
取得されるキーの順序について
かつてのJavaScriptではオブジェクトのプロパティ順序は保証されていませんでしたが、現在の仕様では一定のルールに基づき順序が決まっています。
基本的には、「作成された順序」で配列に格納されますが、数値のように解釈できるキーがある場合は注意が必要です。
数値キー(インデックス)が含まれる場合、それらは昇順で先に並び、その後に文字列キーが追加順で並ぶという挙動を示します。
const data = {
100: "order1",
"apple": "fruit",
2: "order2",
"banana": "fruit"
};
console.log(Object.keys(data));
[ "2", "100", "apple", "banana" ]
このように、数値として扱えるキーが優先的にソートされる仕様を理解しておくことは、予期せぬバグを防ぐために不可欠です。
Object.keysを用いたループ処理のパターン
オブジェクトのプロパティを順番に処理したい場合、Object.keysと配列メソッドを組み合わせる手法が一般的です。
従来のfor...in文を使用する方法もありますが、Object.keysにはプロトタイプチェーン上のプロパティを無視できるという大きなメリットがあります。
forEachを利用した基本的な反復処理
最も頻繁に使用されるのが、forEachメソッドとの組み合わせです。
各キーに対して特定の処理を実行したい場合に適しています。
const config = {
theme: "dark",
fontSize: 16,
showSidebar: true
};
Object.keys(config).forEach(key => {
// keyを使用して値にアクセス
const value = config[key];
console.log(`${key}: ${value}`);
});
theme: dark
fontSize: 16
showSidebar: true
この手法の利点は、スコープが明確になり、コードの可読性が高まることです。
keyという変数に現在のプロパティ名が代入されるため、直感的に処理を記述できます。
mapを利用した新しい配列の生成
オブジェクトのキーをもとに、新しいデータ形式の配列を作成したい場合にはmapメソッドが便利です。
例えば、APIのレスポンス形式を変換したり、UIコンポーネントに渡すためのリストを作成したりする際に多用されます。
const prices = {
apple: 100,
banana: 150,
cherry: 300
};
const labelList = Object.keys(prices).map(key => {
return `${key}は${prices[key]}円です`;
});
console.log(labelList);
[ "appleは100円です", "bananaは150円です", "cherryは300円です" ]
このように、オブジェクトをソースにして配列を生成するパイプラインを構築できるのがObject.keysの強みです。
Object.keysと他のメソッドの比較
オブジェクトを操作するメソッドは、Object.keys以外にもいくつか存在します。
それぞれの特性を理解し、適切な場面で使い分けることが重要です。
Object.keys vs for…in
for...in文は古くから存在するループ処理ですが、Object.keysとは決定的な違いがあります。
それは、「プロトタイプチェーン上のプロパティまで取得するかどうか」という点です。
| 特徴 | Object.keys | for…in |
|---|---|---|
| 対象プロパティ | 自身が持つ列挙可能プロパティのみ | 自身+継承された列挙可能プロパティ |
| 返り値の型 | 配列 | (反復文のためなし) |
| 推奨される用途 | モダンな配列操作を行いたい時 | 古い環境や特殊な継承構造を扱う時 |
実務においては、意図しない継承プロパティの混入を防ぐため、ほとんどのケースでObject.keysが推奨されます。
もしfor...inを使用する場合は、hasOwnPropertyメソッドで自身が持つプロパティかどうかをチェックする処理が必要になり、コードが冗長になりがちです。
Object.valuesおよびObject.entriesとの使い分け
ES2017で追加されたObject.valuesとObject.entriesも、併せて覚えておくべきメソッドです。
Object.keys(obj): キー(プロパティ名)の配列を返すObject.values(obj): 値の配列を返すObject.entries(obj): [キー, 値]のペアを配列の配列として返す
例えば、値だけが必要な場合は、Object.keysを使ってobj[key]と参照するよりも、最初からObject.valuesを使う方がスマートです。
const scores = { math: 90, english: 80, science: 95 };
// 合計点を計算する場合(Object.valuesが最適)
const total = Object.values(scores).reduce((sum, val) => sum + val, 0);
console.log(total); // 265
キーと値の両方を同時に扱いたい場合は、Object.entriesを分割代入と組み合わせて使用するのが2026年現在のベストプラクティスです。
実践的な活用パターン
ここでは、開発現場でよく遭遇する具体的なユースケースを紹介します。
オブジェクトが空かどうかを判定する
JavaScriptでは、if (obj === {})のような比較でオブジェクトが空かどうかを判定することはできません。
オブジェクトの参照先が異なるため、常に偽(false)となってしまうからです。
そこで、Object.keysを利用して「キーの数が0であるか」をチェックする方法が一般的です。
const emptyObj = {};
const filledObj = { id: 1 };
const isEmpty = (obj) => Object.keys(obj).length === 0;
console.log(isEmpty(emptyObj)); // true
console.log(isEmpty(filledObj)); // false
これは、フォームの入力値チェックや、APIのレスポンスが空データでないかを確認する際に非常に重宝します。
特定のプロパティを除外した新しいオブジェクトを作る
不要なプロパティを除外したり、特定の条件に合致するキーのみを抽出したりする場合、reduceと組み合わせる手法が有効です。
const rawData = {
id: 101,
title: "記事タイトル",
temporaryData: "削除したいデータ",
updatedAt: "2026-05-13"
};
// 'temporaryData'を除外したオブジェクトを生成
const filteredData = Object.keys(rawData)
.filter(key => key !== "temporaryData")
.reduce((obj, key) => {
obj[key] = rawData[key];
return obj;
}, {});
console.log(filteredData);
現在のJavaScript環境であれば、スプレッド構文を用いたconst { temporaryData, ...rest } = rawData;という手法も使えますが、動的に除外キーが決まる場合はObject.keysベースの処理が柔軟性に勝ります。
APIリクエストのクエリパラメータを生成する
オブジェクト形式で管理しているパラメータを、URLのクエリ文字列(?name=value&…)に変換する際にも役立ちます。
const params = {
search: "javascript",
page: 2,
sort: "desc"
};
const queryString = Object.keys(params)
.map(key => `${encodeURIComponent(key)}=${encodeURIComponent(params[key])}`)
.join("&");
console.log(`https://example.com/api?${queryString}`);
https://example.com/api?search=javascript&page=2&sort=desc
URLSearchParamsオブジェクトを使用するモダンな方法もありますが、古いブラウザのサポートが必要な環境や、独自のエンコードルールを適用したい場合にはこのロジックが使われます。
注意点とパフォーマンス
Object.keysを使用する際には、いくつか注意すべき制約があります。
シンボル(Symbol)プロパティは取得できない
JavaScriptのプロパティには文字列だけでなく、Symbolを使用することも可能です。
しかし、Object.keysは文字列のキーのみを対象とするため、Symbolで定義されたプロパティは配列に含まれません。
Symbolを含むすべてのキーを取得したい場合は、Reflect.ownKeys()を使用する必要があります。
const secretKey = Symbol("id");
const data = {
[secretKey]: "SECRET_123",
publicName: "公開データ"
};
console.log(Object.keys(data)); // [ "publicName" ]
列挙不可(non-enumerable)なプロパティ
Object.definePropertyなどで、enumerable: falseとして定義されたプロパティも、Object.keysの対象外となります。
通常のオブジェクトリテラルで作成したプロパティはすべて列挙可能ですが、ライブラリやフレームワークが内部的に定義する特殊なプロパティが隠されている場合があることを覚えておきましょう。
大規模なオブジェクトでのパフォーマンス
Object.keysは呼び出された瞬間に新しい配列を生成します。
そのため、数万から数十万のプロパティを持つ極めて巨大なオブジェクトに対して頻繁に実行すると、メモリ消費量が増大し、パフォーマンスに影響を与える可能性があります。
2026年現在の一般的なウェブアプリケーションの規模であれば問題になることは稀ですが、データ集計などの重い処理を行う際は注意が必要です。
まとめ
Object.keysは、JavaScriptでオブジェクトを扱う上で欠かせない非常に汎用性の高いメソッドです。
オブジェクトのキーを配列として取り出すというシンプルな機能ながら、forEachやmap、filterなどの配列メソッドと組み合わせることで、複雑なデータ操作を簡潔に記述できるようになります。
本記事で紹介した「空オブジェクトの判定」や「特定のキーのフィルタリング」などのパターンは、日々の開発において頻出する手法です。
また、Object.valuesやObject.entriesといった関連メソッドと適切に使い分けることで、より読みやすくメンテナンス性の高いコードを実現できます。
プロトタイプチェーンの影響を受けない安全な反復処理として、for...inよりも優先的にObject.keysを活用していきましょう。
今回学んだテクニックを活かし、より効率的なJavaScriptコーディングを実践してみてください。
