---
title: プロパティの列挙可能性と所有権
slug: Web/JavaScript/Enumerability_and_ownership_of_properties
tags:
- Guide
- JavaScript
translation_of: Web/JavaScript/Enumerability_and_ownership_of_properties
---
{{JsSidebar("More")}}
列挙可能プロパティは、内部の列挙可能フラグが true に設定されているプロパティです。これは、単純な代入や初期化で作成されたプロパティのデフォルトです (Object.defineProperty で追加したプロパティはデフォルトで列挙可能性が false になります)。プロパティのキーが Symbol でない限り、列挙可能なプロパティは for...in ループにの対象になります。プロパティの所有権は、プロパティがプロトタイプチェーンではなく、オブジェクトに直接属しているかどうかによって決まります。オブジェクトのプロパティはまとめて取り扱うこともでき、プロパティを検出、反復、列挙、取得するための多くの組み込み機能があります。以下に、使用可能なチャートと不足しているカテゴリを取得する方法を示すサンプルコードを示します。
プロパティの列挙可能性と所有権の検出、取得、反復の組み込みメソッド
機能 |
所有するオブジェクト |
所有するオブジェクトとプロトタイプチェーン |
プロトタイプチェーンのみ |
検出 |
|
列挙可能 |
列挙不可能 |
列挙可能と列挙不可能 |
追加のコードが必要 |
追加のコードが必要 |
in |
|
追加のコードが必要 |
取得 |
|
追加のコードが必要 |
追加のコードが必要 |
反復 |
|
列挙可能 |
列挙不可能 |
列挙可能と列挙不可能 |
for..in
(symbol を除く)
|
追加のコードが必要 |
追加のコードが必要 |
|
追加のコードが必要 |
列挙可能性/所有権によるプロパティの取得
以下に示すのは全てのケースで最も効率的なアルゴリズムではなく、簡潔なデモであることに注意してください。
- 検出は以下の方法で行うことができます。
SimplePropertyRetriever.使いたい get メソッド(obj).indexOf(prop) > -1
- 反復は以下の方法で行うことができます。
SimplePropertyRetriever.使いたい get メソッド(obj).forEach(function (value, prop) {});
(または filter()
, map()
などを使う)
var SimplePropertyRetriever = {
getOwnEnumerables: function(obj) {
return this._getPropertyNames(obj, true, false, this._enumerable);
// Or could use for..in filtered with hasOwnProperty or just this: return Object.keys(obj);
},
getOwnNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, false, this._notEnumerable);
},
getOwnEnumerablesAndNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, false, this._enumerableAndNotEnumerable);
// Or just use: return Object.getOwnPropertyNames(obj);
},
getPrototypeEnumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._enumerable);
},
getPrototypeNonenumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._notEnumerable);
},
getPrototypeEnumerablesAndNonenumerables: function(obj) {
return this._getPropertyNames(obj, false, true, this._enumerableAndNotEnumerable);
},
getOwnAndPrototypeEnumerables: function(obj) {
return this._getPropertyNames(obj, true, true, this._enumerable);
// Or could use unfiltered for..in
},
getOwnAndPrototypeNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, true, this._notEnumerable);
},
getOwnAndPrototypeEnumerablesAndNonenumerables: function(obj) {
return this._getPropertyNames(obj, true, true, this._enumerableAndNotEnumerable);
},
// Private static property checker callbacks
_enumerable: function(obj, prop) {
return obj.propertyIsEnumerable(prop);
},
_notEnumerable: function(obj, prop) {
return !obj.propertyIsEnumerable(prop);
},
_enumerableAndNotEnumerable: function(obj, prop) {
return true;
},
// Inspired by http://stackoverflow.com/a/8024294/271577
_getPropertyNames: function getAllPropertyNames(obj, iterateSelfBool, iteratePrototypeBool, includePropCb) {
var props = [];
do {
if (iterateSelfBool) {
Object.getOwnPropertyNames(obj).forEach(function(prop) {
if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
props.push(prop);
}
});
}
if (!iteratePrototypeBool) {
break;
}
iterateSelfBool = true;
} while (obj = Object.getPrototypeOf(obj));
return props;
}
};
検出テーブル
|
in |
for..in |
obj.hasOwnProperty |
obj.propertyIsEnumerable |
Object.keys |
Object.getOwnPropertyNames |
Object.getOwnPropertyDescriptors |
Reflect.ownKeys() |
列挙可能 |
true |
true |
true |
true |
true |
true |
true |
true |
列挙不可能 |
true |
false |
true |
false |
false |
true |
true |
true |
Symbols キー |
true |
false |
true |
true |
false |
false |
true |
true |
継承された列挙可能 |
true |
true |
false |
false |
false |
false |
false |
false |
継承された列挙不可能 |
true |
false |
false |
false |
false |
false |
false |
false |
継承された Symbols キー |
true |
false |
false |
false |
false |
false |
false |
false |
関連情報
in
for..in
- {{jsxref("Object.hasOwnProperty()")}}
- {{jsxref("Object.propertyIsEnumerable()")}}
- {{jsxref("Object.getOwnPropertyNames()")}}
- {{jsxref("Object.keys()")}}
- {{jsxref("Object.getOwnPropertyDescriptors()")}}