JavaScript | 配列・オブジェクト:オブジェクト基礎 – hasOwnProperty

JavaScript JavaScript
スポンサーリンク

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) を使うと安全で読みやすい。値チェックとは切り分け、配列の穴判定にも活用すれば、初心者でも意図どおりで壊れにくい存在確認が書けます。

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