Object.keys とは何か
Object.keys は「オブジェクトが“自分で持つ”列挙可能なキー(プロパティ名)を、文字列の配列で返す」関数です。ここが重要です:継承(プロトタイプ)上のキーは含まず、Symbol キーは含みません。返ってくるのは“自前の、列挙可能な、文字列キー”だけです。
const user = { id: 1, name: "Alice" };
console.log(Object.keys(user)); // ["id", "name"]
JavaScript返されるキーの範囲と順序(深掘り)
何が含まれて、何が含まれないか
- 含まれる: 自身が持つキー、かつ enumerable: true のもの(通常のオブジェクトリテラルのプロパティ)。
- 含まれない: 継承キー、Symbol キー、non-enumerable なプロパティ(defineProperty で enumerable: false にしたもの)。
const k = Symbol("secret");
const obj = {};
Object.defineProperty(obj, "hidden", { value: 1, enumerable: false });
obj[k] = 123;
obj.visible = 2;
console.log(Object.keys(obj)); // ["visible"]
JavaScript順序の基本ルール
- 数値っぽいキー: 先に昇順で並ぶ(”0″, “1”, “2”, …)。
- それ以外のキー: 追加順で並ぶ。 配列では“存在するインデックスのみ”が文字列として並びます。穴(疎配列)はスキップされます。
const arr = [];
arr[2] = "X";
arr[10] = "Y";
console.log(Object.keys(arr)); // ["2", "10"] ("length" は列挙されない)
JavaScript安全な使い方(例外回避・比較メソッドとの違い)
null/undefined に対するガード
Object.keys は“オブジェクト以外”に使うと TypeError になります。まずガードしましょう。
function safeKeys(x) {
return x != null && typeof x === "object" ? Object.keys(x) : [];
}
JavaScriptObject.values / Object.entries との違い
- Object.keys(obj): キーの配列([“id”,”name”])
- Object.values(obj): 値の配列([1,”Alice”])
- Object.entries(obj): [キー, 値] の配列([[“id”,1],[“name”,”Alice”]])
const obj = { id: 1, name: "Alice" };
Object.values(obj); // [1, "Alice"]
Object.entries(obj); // [["id",1],["name","Alice"]]
JavaScript別の取得系(非列挙や Symbol を含めたいなら)
- Object.getOwnPropertyNames(obj): non-enumerable を含む“文字列キー”を返す。
- Object.getOwnPropertySymbols(obj): Symbol キーを返す。
ループ処理の基本レシピ(可読性重視の定番)
キーで回して値にアクセスする
const obj = { a: 1, b: 2, c: 3 };
for (const key of Object.keys(obj)) {
const value = obj[key];
console.log(`${key}=${value}`);
}
JavaScriptキーでフィルタして作り直す(omit/pick)
// 指定キーを除外(omit)
function omit(obj, keys) {
const out = {};
for (const k of Object.keys(obj)) {
if (!keys.includes(k)) out[k] = obj[k];
}
return out;
}
console.log(omit({ id:1, pw:"x", name:"A" }, ["pw"])); // { id:1, name:"A" }
// 指定キーだけ抽出(pick)
function pick(obj, keys) {
const out = {};
for (const k of keys) {
if (Object.hasOwn(obj, k)) out[k] = obj[k];
}
return out;
}
JavaScript値の整形・検証をしながらコピー
function sanitize(user) {
const out = {};
for (const k of Object.keys(user)) {
const v = user[k];
if (v != null) out[k] = v; // null/undefined を除外
}
return out;
}
JavaScript配列・疎配列に対する理解(穴・length・インデックス)
疎配列は“穴をスキップ”する
const arr = Array(3); // [ <3 empty items> ]
console.log(Object.keys(arr)); // [](存在キーなし)
arr[1] = "B";
console.log(Object.keys(arr)); // ["1"](存在する位置だけ)
JavaScriptlength は列挙対象ではない
配列の “length” は非列挙の自前プロパティです。Object.keys(arr) はインデックスキーのみを返します。
配列データをオブジェクトループしたい時の指針
配列の要素処理は Object.keys よりも、for…of/map/forEach のほうが読みやすく安全です。Object.keys は「位置を文字列キーとして列挙する」ため、配列専用のループ構文を優先しましょう。
実務で役立つパターン(整形・比較・差分)
空オブジェクト判定(“自前の列挙キーがない”)
function isEmpty(obj) {
return Object.keys(obj).length === 0;
}
JavaScript差分検出(変更点だけ拾う)
function diff(a, b) {
const out = {};
for (const k of Object.keys(b)) {
if (b[k] !== a[k]) out[k] = { from: a[k], to: b[k] };
}
return out;
}
JavaScriptキーをソートして安定化(出力や比較に)
function stableEntries(obj) {
return Object.keys(obj).sort().map(k => [k, obj[k]]);
}
JavaScriptよくある落とし穴と回避策(重要ポイントの深掘り)
for…in との混同
- for…in: 継承キーも回り得る。フィルタが必要。
- Object.keys + for…of: “自前の列挙キーだけ”安全に回せる。初心者は基本こちらを使う。
存在判定の誤用
Object.keys(obj).includes(“id”) は“列挙可能な自前キー”しか見ません。継承や非列挙を含めた判定が必要なら in/Object.hasOwn/getOwnPropertyNames を選ぶ。
null/undefined の右辺
Object.keys(null) は例外。必ず x != null && typeof x === "object" でガードしてから使う。
Symbol キーの見落とし
Object.keys は Symbol を返しません。設定や内部フラグに Symbol を使っていると、列挙されずに見落とします。必要なら Object.getOwnPropertySymbols を併用する。
まとめ
Object.keys は「自前の列挙可能な文字列キー」を配列で返す、最もシンプルで安全な反復の入口です。継承キー・non-enumerable・Symbol は対象外で、配列では“存在するインデックスのみ”を返します。null/undefined ガードを徹底し、配列処理には専用のループ構文を優先、存在判定や比較には Object.hasOwn・in・entries/values と使い分ける。これらを押さえるだけで、初心者でも読みやすく堅牢なオブジェクト処理が書けます。

