プロパティの列挙可能性と所有権

列挙可能プロパティは、内部の列挙可能(enumerable)フラグが true に設定されているプロパティです。これは、単純な代入や初期化で作成されたプロパティのデフォルトです (Object.defineProperty で追加したプロパティはデフォルトで列挙可能性が false になります)。プロパティのキーが Symbol でない限り、列挙可能なプロパティは for...in ループにの対象になります。プロパティの所有権は、プロパティがプロトタイプチェーンではなく、オブジェクトに直接属しているかどうかによって決まります。オブジェクトのプロパティはまとめて取り扱うこともでき、プロパティを検出、反復、列挙、取得するための多くの組み込み機能があります。以下に、使用可能なチャートと不足しているカテゴリを取得する方法を示すサンプルコードを示します。

プロパティの列挙可能性と所有権の検出、取得、反復の組み込みメソッド
機能所有するオブジェクト所有するオブジェクトとプロトタイプチェーンプロトタイプチェーンのみ
検出
列挙可能列挙不可能列挙可能と列挙不可能

propertyIsEnumerable

hasOwnProperty

hasOwnPropertypropertyIsEnumerable を使用して列挙可能なものを除外するようにフィルターリング

hasOwnProperty
列挙可能列挙不可能列挙可能と列挙不可能
追加のコードが必要追加のコードが必要in
追加のコードが必要
取得
列挙可能列挙不可能列挙可能と列挙不可能

Object.keys

getOwnPropertyNames

getOwnPropertySymbols

getOwnPropertyNames, getOwnPropertySymbolspropertyIsEnumerable を使用して列挙可能なものを除外するようにフィルターリング

getOwnPropertyNames

getOwnPropertySymbols

追加のコードが必要追加のコードが必要
反復
列挙可能列挙不可能列挙可能と列挙不可能

Object.keys

getOwnPropertyNames

getOwnPropertySymbols

getOwnPropertyNames, getOwnPropertySymbolspropertyIsEnumerable を使用して列挙可能なものを除外するようにフィルターリング

getOwnPropertyNames

getOwnPropertySymbols

列挙可能列挙不可能列挙可能と列挙不可能

for..in

(symbol を除く)

追加のコードが必要追加のコードが必要
追加のコードが必要

列挙可能性/所有権によるプロパティの取得

以下に示すのは全てのケースで最も効率的なアルゴリズムではなく、簡潔なデモであることに注意してください。

  • 検出は以下の方法で行うことができます。 SimplePropertyRetriever.使いたい get メソッド(obj).indexOf(prop) > -1
  • 反復は以下の方法で行うことができます。 SimplePropertyRetriever.使いたい get メソッド(obj).forEach(function (value, prop) {}); (または filter(), map() などを使う)
js
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);
  },
  getEnumerables: function (obj) {
    return this._getPropertyNames(obj, false, true, this._enumerable);
  },
  getNonenumerables: function (obj) {
    return this._getPropertyNames(obj, false, true, this._notEnumerable);
  },
  getEnumerablesAndNonenumerables: function (obj) {
    return this._getPropertyNames(
      obj,
      false,
      true,
      this._enumerableAndNotEnumerable,
    );
  },
  getOwnAndEnumerables: function (obj) {
    return this._getPropertyNames(obj, true, true, this._enumerable);
    // Or could use unfiltered for..in
  },
  getOwnAndNonenumerables: function (obj) {
    return this._getPropertyNames(obj, true, true, this._notEnumerable);
  },
  getOwnAndEnumerablesAndNonenumerables: 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,
    iterateBool,
    includePropCb,
  ) {
    var props = [];

    do {
      if (iterateSelfBool) {
        Object.getOwnPropertyNames(obj).forEach(function (prop) {
          if (props.indexOf(prop) === -1 && includePropCb(obj, prop)) {
            props.push(prop);
          }
        });
      }
      if (!iterateBool) {
        break;
      }
      iterateSelfBool = true;
    } while ((obj = Object.getOf(obj)));

    return props;
  },
};

検出テーブル

infor..inobj.hasOwnPropertyobj.propertyIsEnumerableObject.keysObject.getOwnPropertyNamesObject.getOwnPropertyDescriptorsReflect.ownKeys()
列挙可能truetruetruetruetruetruetruetrue
列挙不可能truefalsetruefalsefalsetruetruetrue
Symbols キーtruefalsetruetruefalsefalsetruetrue
継承された列挙可能truetruefalsefalsefalsefalsefalsefalse
継承された列挙不可能truefalsefalsefalsefalsefalsefalsefalse
継承された Symbols キーtruefalsefalsefalsefalsefalsefalsefalse

関連情報