オブジェクトのキー列挙(Object.keys)の基本と実践
Object.keys は「オブジェクトの“自分が持つ(自前の)列挙可能なプロパティ名”」を配列で返します。設定画面の項目一覧、テーブルのヘッダ生成、動的フォームなどでよく使います。
構文と基本ポイント
const keys = Object.keys(obj);
JavaScript- 返すもの: 文字列キーの配列(自身の列挙可能プロパティのみ、継承は含まない)
- 含まれないもの: Symbolキー、非列挙プロパティ(enumerable: false)、プロトタイプ由来のプロパティ
- 順序の目安: 数字っぽいキー(配列インデックス)→ そのほかの文字列キー(作成順)という並びになることが多い
すぐ使えるテンプレート集
1) 基本:キー一覧を取得
const user = { name: "Aki", age: 22 };
console.log(Object.keys(user)); // ["name","age"]
JavaScript- ポイント: 値が欲しければ Object.values、キーと値のペアなら Object.entries。
2) キー一覧から値を取り出して表示
const settings = { theme: "dark", pageSize: 20, compact: true };
const lines = Object.keys(settings).map(k => `${k}: ${settings[k]}`);
console.log(lines.join("\n"));
/*
theme: dark
pageSize: 20
compact: true
*/
JavaScript- ポイント: keys → map → join の定番パターン。
3) entriesで安全にループ(キーと値を同時に)
const config = { host: "localhost", port: 3000 };
for (const [k, v] of Object.entries(config)) {
console.log(`${k} = ${v}`);
}
JavaScript- ポイント: entriesは「キーと値」を同時に処理できて読みやすい。
4) テーブルのヘッダ生成
const row = { id: 1, name: "Mao", city: "Tokyo" };
const headers = Object.keys(row);
console.log(`<tr>${headers.map(h => `<th>${h}</th>`).join("")}</tr>`);
JavaScript- ポイント: データからUIを動的生成する土台に。
5) 未知のキーを検査(存在チェック)
const obj = { a: 1, b: 2 };
const hasA = Object.keys(obj).includes("a"); // true
JavaScript- ポイント: 速度や明確さ重視なら
"a" in objやObject.hasOwn(obj,"a")も選択肢。
Object.keys と周辺APIの使い分け
- Object.keys(obj): 自身の列挙可能な「文字列キー」一覧。
- Object.values(obj): 自身の列挙可能な「値」一覧。
- Object.entries(obj): 自身の列挙可能な「[キー, 値]」一覧。
- Object.getOwnPropertyNames(obj): 自身の「非列挙も含む」文字列キー一覧。
- Object.getOwnPropertySymbols(obj): 自身の「Symbolキー」一覧。
- for…in: 列挙可能なプロパティを「継承分も含めて」列挙(要 hasOwnProperty で絞り込み推奨)。
実務での便利パターン
列挙可能フラグに注意(定義時に非列挙)
const obj = {};
Object.defineProperty(obj, "hidden", { value: 1, enumerable: false });
obj.visible = 2;
console.log(Object.keys(obj)); // ["visible"](hiddenは出ない)
JavaScript- ポイント: 設計上「出したくないキー」は非列挙にする。
文字列キーだけを対象に(Symbolは別管理)
const sKey = Symbol("secret");
const obj = { a: 1, [sKey]: 999 };
console.log(Object.keys(obj)); // ["a"]
console.log(Object.getOwnPropertySymbols(obj)); // [Symbol(secret)]
JavaScript- ポイント: Symbolはメタ的な用途や衝突回避。列挙対象に含めるなら専用APIで。
配列のキー列挙(インデックスが文字列化)
const arr = ["red", "blue"];
console.log(Object.keys(arr)); // ["0","1"]
JavaScript- ポイント: 配列のキーはインデックス。要素値が必要ならそのまま arr を走査する方が自然。
キー一覧から型チェックやバリデーション
const payload = { id: 10, name: "Aki", extra: "x" };
const allowed = ["id", "name"];
const invalid = Object.keys(payload).filter(k => !allowed.includes(k));
console.log(invalid); // ["extra"]
JavaScript- ポイント: 許容キーを定義して差分で検出。
よくある落とし穴と対策
- プロトタイプ由来が欲しいのに出ない: Object.keysは「自身のみ」。
- 対策: for…inで列挙+hasOwnPropertyで必要に応じて切り替え。プロトタイプを明示的に辿るなら別API。
- 非列挙プロパティが見えない: definePropertyで enumerable: false なものは落ちる。
- 対策: 必要なら Object.getOwnPropertyNames を使う。
- 順序を過信する: 数字っぽいキーが先に並び、その後に文字列キーが作成順というルールがあるが、設計上は「順序に依存しない」方が安全。
- 対策: 表示順を制御したいなら別途キー配列を定義して並べ替える。
- Mapと混同: 普通のオブジェクトは「順序保証や任意キー」に向かない。
- 対策: キー集合が動的・順序が重要・非文字列キーを使いたいなら Map を検討。
練習問題(手を動かして覚える)
- 1. キー一覧を「key=value」形式で出力
const obj = { a: 1, b: 2, c: 3 };
console.log(Object.keys(obj).map(k => `${k}=${obj[k]}`).join(", "));
// "a=1, b=2, c=3"
JavaScript- 2. 許容キー以外を検出して警告
const payload = { id: 1, name: "Mao", debug: true };
const allowed = ["id", "name"];
const extra = Object.keys(payload).filter(k => !allowed.includes(k));
console.log(extra); // ["debug"]
JavaScript- 3. entriesでキーと値を同時にループ
const cfg = { host: "localhost", port: 3000 };
for (const [k, v] of Object.entries(cfg)) {
console.log(`${k}: ${v}`);
}
JavaScript- 4. 非列挙プロパティが keys に出ないことを確認
const obj = {};
Object.defineProperty(obj, "hidden", { value: 1, enumerable: false });
obj.visible = 2;
console.log(Object.keys(obj)); // ["visible"]
JavaScript直感的な指針
- 自前の列挙可能プロパティ名が欲しい: Object.keys。
- 値一覧が欲しい: Object.values。キーと値を同時に処理したいなら Object.entries。
- 非列挙/シンボルも含めたい: getOwnPropertyNames / getOwnPropertySymbols。
- 順序に依存しない設計に: 表示順が必要なら自分でキー順を定義して並べる。
