オブジェクトのプロパティ存在確認

オブジェクトに特定のプロパティが存在するかどうかを確認する方法は複数あります。それぞれに特徴があり、状況に応じて使い分ける必要があります。

in 演算子

in 演算子は、プロパティがオブジェクト自身または継承元に存在するかを確認します。

const user = { name: "田中", age: 25 };

console.log("name" in user);     // true
console.log("email" in user);    // false
console.log("toString" in user); // true(継承されたメソッド)

継承されたプロパティも true を返す点に注意が必要です。

hasOwnProperty()

hasOwnProperty() は、オブジェクト自身が持つプロパティのみを確認します。継承されたプロパティは false を返します。

const user = { name: "田中" };

console.log(user.hasOwnProperty("name"));     // true
console.log(user.hasOwnProperty("toString")); // false(継承されたもの)

Object.hasOwn()

ES2022 で追加された Object.hasOwn() は、hasOwnProperty() のより安全な代替手段です。

const user = { name: "田中" };

console.log(Object.hasOwn(user, "name"));     // true
console.log(Object.hasOwn(user, "toString")); // false
hasOwnProperty()

オブジェクトのメソッドとして呼び出す。プロパティが上書きされていると動作しない可能性がある

Object.hasOwn()

静的メソッドとして呼び出す。より安全で推奨される

// hasOwnProperty が上書きされた危険なケース
const dangerous = {
  hasOwnProperty: () => false
};

dangerous.hasOwnProperty("test"); // 常に false(壊れている)
Object.hasOwn(dangerous, "test"); // 正しく動作

undefined との比較

プロパティの値を undefined と比較する方法もありますが、落とし穴があります。

const user = { name: "田中", email: undefined };

console.log(user.email === undefined); // true
console.log(user.phone === undefined); // true(存在しないのに!)

値が undefined のプロパティと、存在しないプロパティを区別できません。この方法は推奨されません。

オプショナルチェイニング

ネストしたオブジェクトのプロパティを安全に確認するには、オプショナルチェイニング(?.)が便利です。

const user = {
  name: "田中",
  address: { city: "東京" }
};

console.log(user.address?.city);    // "東京"
console.log(user.contact?.email);   // undefined(エラーにならない)

方法の比較

方法継承プロパティ用途
in含む全プロパティの確認
hasOwnProperty()含まない自身のプロパティ確認
Object.hasOwn()含まない推奨される方法

実践的なパターン

条件分岐でプロパティの存在を確認する典型的なパターンです。

function greet(user) {
  if (Object.hasOwn(user, "nickname")) {
    return `Hello, ${user.nickname}!`;
  }
  return `Hello, ${user.name}!`;
}

console.log(greet({ name: "田中" }));                    // "Hello, 田中!"
console.log(greet({ name: "田中", nickname: "たなか" })); // "Hello, たなか!"

プロパティの存在確認には、基本的に Object.hasOwn() を使用するのがおすすめです。継承されたプロパティも含めて確認したい場合のみ、in 演算子を使用してください。