JavaScript | 配列・オブジェクト:オブジェクト操作 – Object.keys

JavaScript JavaScript
スポンサーリンク

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) : [];
}
JavaScript

Object.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"](存在する位置だけ)
JavaScript

length は列挙対象ではない

配列の “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 と使い分ける。これらを押さえるだけで、初心者でも読みやすく堅牢なオブジェクト処理が書けます。

タイトルとURLをコピーしました