hasOwnProperty とは何か
hasOwnProperty は「そのオブジェクト“自身”が、指定したキー(プロパティ)を持っているか」を真偽値で返すメソッドです。ここが重要です:“継承(プロトタイプ)上のキーは含みません”。in 演算子が“自分+継承”を調べるのに対して、hasOwnProperty は“自分だけ”を厳密に判定します。
const base = { kind: "base" };
const obj = Object.create(base); // base を継承
obj.name = "Alice";
console.log(obj.hasOwnProperty("name")); // true(自身のキー)
console.log(obj.hasOwnProperty("kind")); // false(継承キーは除外)
JavaScript基本の使い方(自前のキーだけを確認する)
直接呼び出す
const user = { id: 1, name: "Alice" };
user.hasOwnProperty("id"); // true
user.hasOwnProperty("age"); // false
JavaScriptここが重要です:hasOwnProperty は「キーの存在」を判定します。値が undefined でも“キーがあれば”true になります。
const u = { x: undefined };
u.hasOwnProperty("x"); // true(キーはある)
JavaScript安全な呼び出し(プロトタイプが変でも正しく動かす)
// もっと安全な一般形(推奨)
Object.prototype.hasOwnProperty.call(user, "id");
JavaScriptここが重要です:対象が「hasOwnProperty を上書きしている」「プロトタイプが切られている(Object.create(null))」などでも、常に正しく動きます。
in 演算子や Object.hasOwn との違い(選び方の核心)
in 演算子との違い
in は“自分+継承”を含めた存在判定、hasOwnProperty は“自分だけ”。
const base = { kind: "base" };
const obj = Object.create(base);
("kind" in obj); // true(継承にある)
obj.hasOwnProperty("kind"); // false(自分には無い)
JavaScriptここが重要です:データ検証や“送るフィールドを自分のキーだけに限定したい”場面では hasOwnProperty が適切です。UI の既定値を継承で提供するような場面では in が便利です。
Object.hasOwn(ES2022)の推奨
Object.hasOwn(obj, "name"); // true/false(静的メソッド)
JavaScriptここが重要です:Object.hasOwn は“上書きやプロトタイプの影響”を受けず、call を書かずに済むため読みやすく安全です。新しめの環境ならこちらを使いましょう。
よくある落とし穴と回避(深掘り)
hasOwnProperty を上書きしてしまう
const bad = { hasOwnProperty: () => false }; // 上書き
// bad.hasOwnProperty("x") は信用できない
Object.prototype.hasOwnProperty.call(bad, "x"); // これなら安全
JavaScriptここが重要です:第三者からの入力・不明な形のオブジェクトには“call で呼ぶ”のが鉄則です。
Object.create(null)(プロトタイプ無し)での判定
const dict = Object.create(null);
dict.id = 1;
// dict.hasOwnProperty は undefined(持っていない)
Object.prototype.hasOwnProperty.call(dict, "id"); // true(安全に判定)
JavaScript値と存在の混同
const obj = { a: 0, b: null };
obj.hasOwnProperty("a"); // true(キーあり、値は 0)
obj.hasOwnProperty("b"); // true(キーあり、値は null)
obj.hasOwnProperty("c"); // false(キーなし)
JavaScriptここが重要です:“存在判定”と“値の内容”は別です。値チェックは === undefined や === null などで行います。
配列・疎配列での使い方(穴の判定に強い)
スロットに値があるか(“穴”かどうか)
const arr = [];
arr[2] = "X"; // [ <2 empty items>, "X" ]
0 in arr; // false(穴)
arr.hasOwnProperty(0); // false(自前のキーなし)
arr.hasOwnProperty(2); // true(自前のキーあり)
JavaScriptここが重要です:配列の“穴”判定に hasOwnProperty は有効です。forEach/map は穴をスキップする挙動と合わせて理解すると、ループ設計が安定します。
実践レシピ(安全な存在チェックと整形)
必須フィールドの検証(継承を除外)
function validateUser(u) {
if (u == null) return { ok: false, reason: "missing object" };
if (!Object.hasOwn(u, "id")) return { ok: false, reason: "missing id" };
if (!Object.hasOwn(u, "name")) return { ok: false, reason: "missing name" };
return { ok: true };
}
JavaScript送信前に“自前のキーだけ”収集
function ownEntries(obj) {
const out = [];
for (const k in obj) {
if (Object.hasOwn(obj, k)) out.push([k, obj[k]]);
}
return out;
}
JavaScriptユーザー入力キーの安全化(危険キーを除外)
function safeAssign(target, input) {
for (const [k, v] of Object.entries(input)) {
if (!["__proto__", "constructor", "prototype"].includes(k)) {
target[k] = v;
}
}
return target;
}
JavaScriptここが重要です:プロトタイプ汚染の温床になり得るキーは受け付けない。存在判定は Object.hasOwn を使うと堅牢です。
まとめ
hasOwnProperty は“自分が持つキーだけ”を判定するための基礎メソッドです。継承を含める in と役割が違い、入力検証や送信フィールドの限定に適しています。未知のオブジェクトやプロトタイプなしの辞書には Object.prototype.hasOwnProperty.call(obj, key) を、環境が対応しているなら Object.hasOwn(obj, key) を使うと安全で読みやすい。値チェックとは切り分け、配列の穴判定にも活用すれば、初心者でも意図どおりで壊れにくい存在確認が書けます。

