obj.key !== undefined で、プロパティの存在を調べたつもりになっていませんか。値が undefined の項目と、存在しない項目は、この判定では区別できません。逆に in は、プロトタイプから継承した項目も見つけます。
値の確認と、項目の存在確認を分けて実測します。
実行環境
2026年10月25日、macOS 27.0.1、Node.js v24.22.1(darwin / arm64)で以下のコードを実行しました。ブラウザ、Windows、Proxyオブジェクトについては試していません。
同じ3項目でも、3種類の判定は違う
const settings = Object.create({ theme: 'dark' });
settings.limit = undefined;
for (const key of ['theme', 'limit', 'missing']) {
console.log(
key,
Object.hasOwn(settings, key),
key in settings,
settings[key] !== undefined,
);
}
出力の列は、キー・自身の項目・継承込みの存在・値がundefined以外、の順です。
theme false true true
limit true true false
missing false false false
theme はプロトタイプからの継承です。in はプロトタイプも調べるため true。値は 'dark' なので最後の判定も true です。
自身の項目 limit の値は undefined。存在判定2つは true でも値との比較は false で、missing と区別できません。
自身の項目なら Object.hasOwn、継承も含むなら in。使える値かどうかは、別に型や範囲を確認します。
hasOwnPropertyを直接呼べないオブジェクト
const bare = Object.create(null);
bare.name = 'Alice';
console.log('bare', Object.hasOwn(bare, 'name'), typeof bare.hasOwnProperty);
const shadow = { hasOwnProperty: false };
console.log('shadow', Object.hasOwn(shadow, 'hasOwnProperty'));
bare true undefined
shadow true
bare は通常のプロトタイプを持たず、hasOwnProperty メソッドがありません。shadow は同名項目が false。どちらも obj.hasOwnProperty(key) を直接呼べません。
Object.hasOwn は対象の同名メソッドに依存しません。ただし、対象がオブジェクトかという入力検証まで済むわけではありません。
存在判定はgetterの値を読まない
普通のオブジェクトにgetterを定義し、読み出し回数を数えました。
let reads = 0;
const lazy = {
get name() {
reads++;
return 'Alice';
},
};
console.log('own', Object.hasOwn(lazy, 'name'), 'reads', reads);
console.log('value', lazy.name, 'reads', reads);
own true reads 0
value Alice reads 1
この例では存在判定はgetterを実行せず、値を読んだ行で回数が1になります。Proxyも含めて副作用がない、という主張ではありません。
AIにチェックを頼むときも、継承した項目・自身のundefined・存在しない項目で、期待する結果と比較できます。
参照
未経験者向けの体験版を公開しています
- ▶ ライブデモ(インストール不要・無料)→ https://trial-web-ayies128s-projects.vercel.app/?ref=qiita
- 無料体験版(git clone して手元で動かす・⭐ Star もよろしくお願いします)→ https://github.com/ayies128/next-ai-camp-trial
- YouTube『AIエンジニア情報局』(AI×開発ニュースを1本5分で)→ https://www.youtube.com/channel/UC1rXVD9WYsQPQEWZyd-A1KA/?ref=qiita
※ 中上級者には易しすぎる内容なので、初心者の知り合いへの紹介や社内研修の参考としてどうぞ。