1. ホーム
  2. javascript

[解決済み] オブジェクトの列挙不可能な継承プロパティ名を取得することは可能ですか?

2022-09-20 10:36:25

質問

JavaScriptでは、オブジェクトのプロパティを取得する方法がいくつかあり、取得したいものに応じて使い分けています。

1) Object.keys() これは、ECMA5メソッドである、オブジェクトのすべての自身の、列挙可能なプロパティを返します。

2) a for...in ループで、オブジェクトのすべての列挙可能なプロパティを、それらが自身のプロパティであるか、プロトタイプチェーンから継承されているかに関係なく、返します。

3) Object.getOwnPropertyNames(obj) これは、列挙可能かどうかにかかわらず、オブジェクトのすべてのプロパティを返します。

また、以下のようなメソッドもあります。 hasOwnProperty(prop) は、あるプロパティが継承されているか、実際にそのオブジェクトに属しているかをチェックします。 propertyIsEnumerable(prop) はその名が示すように、プロパティが列挙可能かどうかをチェックします。

これら全てのオプションでは 非列挙可能、非所有 プロパティを取得する方法はありません。これを行う方法はあるのでしょうか?言い換えれば、私はどうにかして継承された非列挙可能なプロパティのリストを取得することができますか?

ありがとうございます。

どのように解決するのですか?

では getOwnPropertyNames は非列挙可能なプロパティを得ることができるので、それを使ってプロトタイプチェーンを歩くことと組み合わせることができます。

function getAllProperties(obj){
    var allProps = []
      , curr = obj
    do{
        var props = Object.getOwnPropertyNames(curr)
        props.forEach(function(prop){
            if (allProps.indexOf(prop) === -1)
                allProps.push(prop)
        })
    }while(curr = Object.getPrototypeOf(curr))
    return allProps
}

Safari 5.1でテストしたところ、以下のようになりました。

> getAllProperties([1,2,3])
["0", "1", "2", "length", "constructor", "push", "slice", "indexOf", "sort", "splice", "concat", "pop", "unshift", "shift", "join", "toString", "forEach", "reduceRight", "toLocaleString", "some", "map", "lastIndexOf", "reduce", "filter", "reverse", "every", "hasOwnProperty", "isPrototypeOf", "valueOf", "__defineGetter__", "__defineSetter__", "__lookupGetter__", "propertyIsEnumerable", "__lookupSetter__"]


更新しました。 コードを少しリファクタリングしました(スペース、中括弧を追加し、関数名を改善しました)。

function getAllPropertyNames( obj ) {
    var props = [];

    do {
        Object.getOwnPropertyNames( obj ).forEach(function ( prop ) {
            if ( props.indexOf( prop ) === -1 ) {
                props.push( prop );
            }
        });
    } while ( obj = Object.getPrototypeOf( obj ) );

    return props;
}