JavaScript 逆引き集 | プロパティの存在チェック

JavaScript JavaScript
スポンサーリンク

プロパティの存在チェック(’prop’ in obj)の基本と実践

「そのプロパティある?」を最短で判定するのが in 演算子。自前のプロパティだけでなく、プロトタイプから継承されたプロパティも「存在する」と判定します。


基本の挙動と書き方

const user = { name: "Aki", age: 22 };

console.log("name" in user);     // true
console.log("address" in user);  // false
JavaScript
  • 判定対象: オブジェクト自身+プロトタイプチェーン上の列挙/非列挙プロパティも含めて「名前があるか」を判定。
  • 戻り値: true/false のブール値。
  • 注意: 値が undefined でも「プロパティが存在すれば」true。
const obj = { key: undefined };
console.log("key" in obj);         // true(存在する)
console.log(obj.key !== undefined); // false(値は未定義)
JavaScript

すぐ使えるテンプレート集

継承プロパティも含めて存在確認(in)

const obj = {};
console.log("toString" in obj); // true(Object.prototype由来)
JavaScript
  • ポイント: 「とにかく名前があるか」を見たいときは in がラク。

自前プロパティだけ確認(Object.hasOwn)

const obj = Object.create({ inherited: 1 });
obj.own = 2;

console.log(Object.hasOwn(obj, "own"));       // true
console.log(Object.hasOwn(obj, "inherited")); // false
JavaScript
  • ポイント: 継承を含めたくないなら Object.hasOwn(obj, key) が明快。

古典的な自前判定(hasOwnProperty)

const obj = { a: 1 };
console.log(obj.hasOwnProperty("a")); // true
JavaScript
  • ポイント: 既存コードでよく見る。安全に使うなら Object.prototype.hasOwnProperty.call(obj, key)

値が設定済みかを確認(存在+未定義の区別)

const payload = { id: 0, name: "" }; // falsyでも“値はある”

console.log("id" in payload);              // true
console.log(payload.id !== undefined);     // true
console.log(Boolean(payload.id));          // false(値は0 = falsy)
JavaScript
  • ポイント: 「キーの存在」「未定義でない」「truthy/falsey」は別概念。

安全アクセス(Optional chaining)

const obj = { user: { profile: { city: "Tokyo" } } };
console.log(obj.user?.profile?.city ?? "N/A"); // "Tokyo"
console.log(obj.admin?.profile?.city ?? "N/A"); // "N/A"
JavaScript
  • ポイント: 存在チェックとアクセスを一度に。落ちずに安全。

実務での使い分け

  • プロパティ名がオブジェクトに“どこか”にあればOK:
    • おすすめ: 'key' in obj
  • 自前のキーだけか知りたい(継承除外):
    • おすすめ: Object.hasOwn(obj, 'key')
  • 値が設定されているか(未定義でないか):
    • おすすめ: obj.key !== undefined
  • ネストアクセスを安全に:
    • おすすめ: obj?.nested?.key?? でデフォルト付与

よくある落とし穴と対策

  • undefinedと「不存在」を混同: 値がundefinedでもキーがあれば in はtrue。
    • 対策: キーの有無は in/自前判定は Object.hasOwn/値確認は !== undefined を使い分け。
  • 配列で値の存在を in で調べる誤用:in はインデックスの存在判定(”0″ in arr)。値の存在は arr.includes(value)
    • 対策: 目的に合ったAPIを使う(配列はincludes、Setはhas)。
  • hasOwnPropertyの偽装/上書き: オブジェクトが独自の hasOwnProperty を持つと危険。
    • 対策: Object.hasOwn(obj, key)Object.prototype.hasOwnProperty.call(obj, key) を使用。
  • プロトタイプ由来を意図せず拾う: 既定メソッドまでtrueになる。
    • 対策: 継承を除外したいときは必ず Object.hasOwn

練習問題(手を動かして覚える)

// 1) in と hasOwn の違い
const base = { inherited: 1 };
const obj = Object.create(base);
obj.own = 2;

console.log("inherited" in obj);            // true
console.log(Object.hasOwn(obj, "inherited"));// false
console.log(Object.hasOwn(obj, "own"));      // true

// 2) undefined と不存在の違い
const a = { x: undefined };
console.log("x" in a);            // true
console.log(a.x !== undefined);   // false
console.log("y" in a);            // false

// 3) 配列での誤用回避
const arr = ["red", "blue"];
console.log(0 in arr);                // true(インデックス0はある)
console.log(arr.includes("red"));     // true(値"red"はある)
JavaScript

直感的な指針

  • 名前の存在(継承含む): 'key' in obj
  • 自分が持つキーだけ: Object.hasOwn(obj, 'key')
  • 値が設定済みか: obj.key !== undefined
  • 配列の値存在: arr.includes(value) を使う

この3つの視点(キーの存在/自前かどうか/値の有無)を分けて考えると、混乱が消えます。

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