JavaScript | 基礎構文:オブジェクト – in 演算子

JavaScript JavaScript
スポンサーリンク

in 演算子とは何か

in 演算子は、あるキー(プロパティ名)がオブジェクトに「存在するか」を調べるための演算子です。結果は真偽値(true/false)。存在確認に特化していて、値が何であるか(undefinedかどうか)とは関係なく、「キーがあるか」を判定します。

const user = { name: "太郎", age: 20 };

console.log("name" in user); // true
console.log("city" in user); // false
JavaScript

存在確認の意味(undefined との違いを深掘り)

「キーがあるか」と「値があるか」は別物です。in は「キーの有無」を見ます。値が undefined でもキーが存在すれば true になります。一方、obj.key === undefined は「値が未定義か」を見るだけで、キー自体の有無は判別できません(値が undefined として設定されている場合と、キーが存在しない場合を区別できない)。

const obj = { a: undefined };

console.log("a" in obj);            // true(キーは存在)
console.log(obj.a === undefined);   // true(値が未定義)

console.log("b" in obj);            // false(キーがない)
console.log(obj.b === undefined);   // true(キーがない場合も undefined と比較で true)
JavaScript

ここが重要です:キーの有無を正しく判定したいなら in。値が未設定かどうかだけを判定したいなら比較(=== undefined)を使います。


プロトタイプまで含めた探索(hasOwnProperty との違い)

in は「そのオブジェクト自身のプロパティ」だけでなく、プロトタイプチェーン上にある継承プロパティも存在として数えます。対して hasOwnProperty は「自分が持つプロパティに限定」します。

const parent = { shared: 1 };
const child = Object.create(parent); // parent を継承
child.own = 2;

console.log("own" in child);     // true(自分のプロパティ)
console.log("shared" in child);  // true(継承プロパティも含む)
console.log(child.hasOwnProperty("shared")); // false(自分のではない)
JavaScript

ここが重要です:継承を含めて「使えるキーか」を確認するなら in、自分が持つデータに限定して確認したいなら hasOwnProperty を使い分けます。


配列と in(数値インデックスの扱い)

配列でも in は使えます。配列のインデックス(0, 1, 2…)が“キーとして存在するか”を判定します。delete で要素を消すと“穴”になり、インデックスキーが消えるので infalse を返します。splice で取り除くと詰められるため、該当インデックスの存在も変わります。

const arr = [10, 20, 30];
console.log(0 in arr); // true
console.log(3 in arr); // false

delete arr[1];
console.log(arr);        // [10, <1 empty item>, 30]
console.log(1 in arr);   // false(キーが消えた=穴)

arr.splice(1, 1);        // 詰める
console.log(arr);        // [10, 30]
console.log(1 in arr);   // true(今は 30 が入っている)
JavaScript

ここが重要です:配列の“存在判定”をしたいときは in が有効ですが、要素が「空の値」か「存在しない」かの違いに注意しましょう。


ブラケット記法との組み合わせ(動的キーの存在確認)

in の左側は文字列(またはシンボル)です。変数に入ったキー名で存在確認したいときはブラケット記法の発想で「動的キー」を扱います。

const user = { name: "太郎", "fav-color": "blue" };

const key = "fav-color";
console.log(key in user);      // true(動的キー)
console.log("fav-color" in user); // true(文字列リテラル)
JavaScript

ここが重要です:obj.keykey in obj は別概念です。前者は固定キーにアクセス、後者はキー文字列(変数の中身)で存在判定。


in とオプショナルチェーン(安全なアクセスの設計)

存在確認をした上で値を読むなら、in と通常アクセス(obj[key])を組み合わせるか、存在が曖昧なネストにはオプショナルチェーン ?. を使います。

const user = { profile: { city: "東京" } };

// inで確認してから読む
if ("profile" in user) {
  console.log(user.profile.city); // プロパティが存在する前提なら安全
}

// ネストが不明なら ?. を使う
console.log(user.profile?.city);  // 東京
console.log(user.address?.city);  // undefined(途中がなければ止まる)
JavaScript

ここが重要です:in は「キーがあるか」を判定する道具、?. は「途中がなければそこでやめる」ための道具。場面に応じて使い分けると、実行時エラーを避けられます。


宣言された変数やクラスへの in(対象の違い)

in は「オブジェクトのプロパティ」を調べる演算子です。変数(識別子)そのものやクラス名に対しては使えません。グローバルオブジェクト(ブラウザなら window)に対しては、グローバルに公開されたプロパティの存在確認に使えます。

// 変数に対しては in は使えない(オブジェクトではないため)
// console.log("x" in x); // エラー

// グローバルオブジェクトのプロパティ確認
window.temp = 123;
console.log("temp" in window); // true
JavaScript

ここが重要です:in の右側は必ず「オブジェクト」。存在確認したい対象がプロパティであることを意識しましょう。


まとめ

in 演算子は「キーが存在するか」を判定するための道具で、値が undefined かどうかとは独立しています。プロトタイプ継承も含めて存在を調べるため、継承を含めて“使えるキーか”を確認したい場面に向いています。自分のプロパティだけに限定したいなら hasOwnProperty を使い、配列ではインデックスキーの存在と“穴”の有無を見分けられます。動的キーの存在確認やネストの安全なアクセスと組み合わせることで、誤判定と実行時エラーを抑え、意図通りのロジックを書けるようになります。

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