Object.prototype.propertyIsEnumerable()

propertyIsEnumerable() メソッドは、指定されたプロパティが列挙可能で、かつオブジェクト自身のプロパティであるかどうかを示す論理値を返します。

試してみましょう

構文

js
propertyIsEnumerable(prop)

引数

prop

調べたいプロパティの名前です。文字列または Symbol が指定できます。

返値

論理値で、指定されたプロパティが列挙可能であり、かつオブジェクト自身のプロパティであるかどうかを示します。

解説

すべてのオブジェクトは Object.prototype から(つまり、 null プロトタイプオブジェクトを除くすべてが) propertyIsEnumerable メソッドを継承しています。このメソッドは、指定したプロパティ(文字列またはシンボル)がオブジェクトの列挙可能な自分自身のプロパティであるかどうかを判定します。オブジェクトが指定したプロパティを持っていない場合、このメソッドは false を返します。

このメソッドは Object.getOwnPropertyDescriptor(obj, prop)?.enumerable ?? false と等価です。

propertyIsEnumerable() の基本的な使い方

以下の例はオブジェクトと配列での propertyIsEnumerable() の使い方を示しています。

js
const o = {};
const a = [];
o.prop = "is enumerable";
a[0] = "is enumerable";

o.propertyIsEnumerable("prop"); // true
a.propertyIsEnumerable(0); // true

ユーザー定義オブジェクトと組み込みオブジェクト

以下の例は、ユーザー定義プロパティと組み込みプロパティの列挙可能性を実証しています。

js
const a = ["is enumerable"];

a.propertyIsEnumerable(0); // true
a.propertyIsEnumerable("length"); // false

Math.propertyIsEnumerable("random"); // false
globalThis.propertyIsEnumerable("Math"); // false

直接のプロパティと継承されたプロパティ

列挙可能な自分自身で持つプロパティだけが propertyIsEnumerable()true を返しますが、継承されたものを含むすべての列挙可能なプロパティは for...in ループによって処理されます。

js
const o1 = {
  enumerableInherited: "is enumerable",
};
Object.defineProperty(o1, "nonEnumerableInherited", {
  value: "is non-enumerable",
  enumerable: false,
});
const o2 = {
  // o1 は o2 のプロトタイプ
  __proto__: o1,
  enumerableOwn: "is enumerable",
};
Object.defineProperty(o2, "nonEnumerableOwn", {
  value: "is non-enumerable",
  enumerable: false,
});

o2.propertyIsEnumerable("enumerableInherited"); // false
o2.propertyIsEnumerable("nonEnumerableInherited"); // false
o2.propertyIsEnumerable("enumerableOwn"); // true
o2.propertyIsEnumerable("nonEnumerableOwn"); // false

シンボルプロパティの検査

propertyIsEnumerable()シンボルプロパティにも対応しています。なお、多くの列挙メソッドは、文字列プロパティのみを扱います。シンボルプロパティの列挙可能性は、Object.assign()スプレッド構文を使用している場合にのみ有益です。詳細については、プロパティの列挙可能性と所有権を参照してください。

js
const sym = Symbol("enumerable");
const sym2 = Symbol("non-enumerable");
const o = {
  [sym]: "is enumerable",
};
Object.defineProperty(o, sym2, {
  value: "is non-enumerable",
  enumerable: false,
});

o.propertyIsEnumerable(sym); // true
o.propertyIsEnumerable(sym2); // false

null プロパティオブジェクトの使用

null プロトタイプオブジェクトは Object.prototype を継承していないため、 propertyIsEnumerable() メソッドを継承しません。代わりにオブジェクトを this として Object.prototype.propertyIsEnumerable を呼び出す必要があります。

js
const o = {
  __proto__: null,
  enumerableOwn: "is enumerable",
};

o.propertyIsEnumerable("enumerableOwn"); // TypeError: o.propertyIsEnumerable は関数ではありません
Object.prototype.propertyIsEnumerable.call(o, "enumerableOwn"); // true

また、代わりに Object.getOwnPropertyDescriptor() を使用することもできます。これは、存在しないプロパティと実際に列挙できないプロパティを判別するのにも有益です。

js
const o = {
  __proto__: null,
  enumerableOwn: "is enumerable",
};

Object.getOwnPropertyDescriptor(o, "enumerableOwn")?.enumerable; // true
Object.getOwnPropertyDescriptor(o, "nonExistent")?.enumerable; // undefined

仕様書

Specification
ECMAScript Language Specification
# sec-object.prototype.propertyisenumerable

ブラウザーの互換性

BCD tables only load in the browser

関連情報