JavaScriptオブジェクトのプロパティをリストする方法は?


842

次のようにオブジェクトを作成するとします。

var myObject =
        {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"};

プロパティ名のリストを取得する最良の方法は何ですか?つまり、次のようないくつかの変数「キー」で終了したいと思います。

keys == ["ircEvent", "method", "regex"]

3
少し外れたトピックですが、underscore.jsを使用する場合:_.keys(myJSONObject)
Endy Tjahjono '28

回答:


1076

最新のブラウザー(IE9 +、FF4 +、Chrome5 +、Opera12 +、Safari5 +)では、組み込みのObject.keysメソッドを使用できます。

var keys = Object.keys(myObject);

上記は完全なポリフィルですが、簡略化されたバージョンは次のとおりです。

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

または、var getKeysと置き換えて、任意のオブジェクトObject.prototype.keysを呼び出すこと.keys()ができます。プロトタイプの拡張にはいくつかの副作用があり、私はそれを行うことをお勧めしません。


17
「プロトタイプをオブジェクト化するためにこれを実行したくなるかもしれませんが、しないでください!」という効果に再度更新します。
AnthonyWJones 2008年

4
誰かに光を当てたいのですが、なぜオブジェクトのプロトタイプに関数を追加することが推奨されないのですか?
ヴィシュワナート

2
それ自体はまったく別の質問です
。stackoverflow

3
このfor (var key in myObject) {...}手法は、ブラウザーやV8以外のJavaScriptランタイムで役立ちます。たとえば、JavaScriptのmap-reduceクエリをRiakに渡す場合、Objectオブジェクトは存在しないため、Object.keysメソッドは使用できません。
ekillaby 2013年

19
@slashnick「簡略版」は、オブジェクトのプロトタイプチェーン内のすべてのプロパティを返します(「for ... in」を使用しているため)。一方、(ECMAScript 5.1)Object.keysメソッドは、オブジェクト自体のプロパティのみを返します。それは重要な違いだと思います。
Martin Carel 2014年

255

以下のようslashnickは指摘し、あなたはその属性名のオブジェクトを反復処理するために構築物「には、」使用することができます。ただし、オブジェクトのプロトタイプチェーンのすべての属性名を繰り返し処理します。オブジェクト自体の属性のみを反復処理する場合は、Object#hasOwnProperty()メソッドを使用できます。したがって、次のようになります。

for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        /* useful code here */
    }
}

25
上記のスラッシュの答えの前にこれを読んだらいいのに。escオブジェクトには約100万のプロパティがあり、そのほとんどが使用されておらず、アラートがあったため、キーを押したまま15分間費やす必要がありました。
Mark Henderson、

ここでZakas自分でテーマに関する優秀記事です:nczonline.net/blog/2010/07/27/...は
パブロ・カブレラ

4
笑@MarkHenderson-次回は、ブラウザのプロセスを終了して、15分を無駄にする代わりに再起動します:)
JD Smith

-関連する機能はobj.getOwnPropertyNames()であるdeveloper.mozilla.org/en-US/docs/JavaScript/Reference/...
スティーブ・グッドマン

@MarkHenderson console.logを使用しないのはなぜですか?
ラザニアAndroid 2014年

102

サム・ダットンが答えたように、まさにこの目的のための新しい方法がECMAScript 5th Editionに導入されました。 Firefox 4、Chrome 6、Safari 5、IE 9でObject.keys()サポートされています。

また、このメソッドをサポートしていないブラウザでメソッドを非常に簡単に実装することもできます。ただし、一部の実装では、Internet Explorerとの完全な互換性がありません。より互換性のあるソリューションを次に示します。

Object.keys = Object.keys || (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !{toString:null}.propertyIsEnumerable("toString"),
        DontEnums = [ 
            'toString', 'toLocaleString', 'valueOf', 'hasOwnProperty',
            'isPrototypeOf', 'propertyIsEnumerable', 'constructor'
        ],
        DontEnumsLength = DontEnums.length;

    return function (o) {
        if (typeof o != "object" && typeof o != "function" || o === null)
            throw new TypeError("Object.keys called on a non-object");

        var result = [];
        for (var name in o) {
            if (hasOwnProperty.call(o, name))
                result.push(name);
        }

        if (hasDontEnumBug) {
            for (var i = 0; i < DontEnumsLength; i++) {
                if (hasOwnProperty.call(o, DontEnums[i]))
                    result.push(DontEnums[i]);
            }   
        }

        return result;
    };
})();

現在受け入れられている回答には、hasOwnProperty()のチェックが含まれておらず、プロトタイプチェーンを通じて継承されるプロパティが返されることに注意してください。また、Internet Explorerの有名なDontEnumバグについても説明していません。プロトタイプチェーンの列挙できないプロパティが原因で、同じ名前のローカルで宣言されたプロパティがDontEnum属性を継承します。

Object.keys()を実装すると、より堅牢なソリューションが得られます。

編集: Prototypeの有名な貢献者であるkangaxとの最近の議論に続いて、私Object.forIn()ここにある彼の関数のコードに基づいてDontEnumバグの回避策を実装しまし


すばらしい答えです。常にJSON dictであると仮定すると、受け入れられた答えは、最も正確な解決策であり続けると思います。これは確かに他の場所で使用するものです。
David Snabel-Caunt

1
@David Caunt:ありがとう:-)残念ながら、受け入れられた答えはDontEnumバグのファウルになり、どのJSONオブジェクトがそのキーの1つとして「valueOf」や「constructor」のような文字列を持っているかもしれません。また、への拡張を反復しObject.prototypeます。ただし、短いコードの方が大きくて堅牢なコードよりもはるかに魅力的であるように見えることがよくありますが、この答えのポイントはObject.keys()、このコードを使用してそれをサポートしないブラウザーに実装できるECMAScript 5thを使用することです。ネイティブバージョンは、これよりもさらにパフォーマンスが高くなります。
アンディE

2
とても素敵な、アンディ:)私は、ES5 はオブジェクトの列挙可能なプロパティにObject.keys対応する文字列の配列しか返さないことを思い出したいと思います-このスレッドでは誰も言及していません- これは、ネイティブ(ユーザー定義)オブジェクトを操作する場合は重要ではないかもしれませんが、ホストオブジェクトで非常によく見えるはずです(ただし、指定されていないホストオブジェクトの動作は別の—痛い—ストーリーです)。すべての(列挙できないものを含む)プロパティを列挙するために、ES5は提供しています(互換性の表でサポートを参照してください。kangax.github.com/es5 -compat- tableObject.getOwnPropertyNames
kangax

2
このソリューションをes5-shimに統合しましたgithub.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390
Kris Kowal

2
これがなぜ実装されObject.keys(stuff)ているのstuff.keys()か、そうでないのかを誰かが説明できますか?
Blazemonger、2011

32

Object.keysおよびその他のECMAScript 5メソッドは、Firefox 4、Chrome 6、Safari 5、IE 9以降でサポートされています。

例えば:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ECMAScript 5互換性テーブル:http : //kangax.github.com/es5-compat-table/

新しいメソッドの説明:http : //markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/


また、クローム開発ツールのコンソール、Firebugは、などのキーを()チェックアウト
サム・ダットンに


28

Object.getOwnPropertyNames(obj)

この関数は、で表示されるプロパティに加えて、列挙不可能なプロパティも表示しObject.keys(obj)ます。

JSでは、すべてのプロパティにブール値を含むいくつかのプロパティがありますenumerable

一般に、列挙できないプロパティはより「内部的」であり、あまり使用されませんが、実際に何が起こっているかを確認するために時々それらを調べることは洞察力があります。

例:

var o = Object.create({base:0})
Object.defineProperty(o, 'yes', {enumerable: true})
Object.defineProperty(o, 'not', {enumerable: false})

console.log(Object.getOwnPropertyNames(o))
// [ 'yes', 'not' ]

console.log(Object.keys(o))
// [ 'yes' ]

for (var x in o)
    console.log(x)
// yes, base

また、方法に注意してください:

  • Object.getOwnPropertyNamesそして、プロトタイプチェーンを上って検索Object.keys しないくださいbase
  • for in する

ここでプロトタイプチェーンの詳細:https : //stackoverflow.com/a/23877420/895245


16

私はダンプ機能の大ファンです。

http://ajaxian.com/archives/javascript-variable-dump-in-coldfusion 代替テキスト


1
+1(似たようなものではありません)を構築する目的でここに来たため。
Camilo Martin、

1
netgrow.com.au/assets/files/dump/dump.zipが見つかりません ダンプJavaScriptをダウンロードするに
Kiquenet

@Kiquenetこのようなものを構築するたびに、通常のオブジェクトインスペクターで解決します。HTMLでレンダリングしたい場合は、npmモジュールなどがあります。率直に言って、私が行き詰まったのは、そのイメージにあるものよりも良いものが欲しかったが、それを概念化することができなかったことです。インスペクターでオブジェクトを参照するのは難しいですが、任意のオブジェクトから意味を推測しようとするヒューリスティック(たとえば、オブジェクトの配列を列を持つテーブルに並べ替える)は、実際に機能するとは限りません。
Camilo Martin

Pretty Print JavaScript についてはどうhttps://j11y.io/demos/prettyprint/ですか?
Kiquenet

13

次のようにjQueryでそれを行うことができます:

var objectKeys = $.map(object, function(value, key) {
  return key;
});

9

要素のみを取得し、関数は取得しない場合、このコードが役立ちます

this.getKeys = function() {

    var keys = new Array();
    for(var key in this) {

        if( typeof this[key] !== 'function') {

            keys.push(key);
        }
    }
    return keys;
}

これはHashMapの実装の一部であり、キーだけが必要です。「this」はキーを含むハッシュマップオブジェクトです


8

これはIE8でもほとんどのブラウザーで機能し、ライブラリーは必要ありません。var iが鍵です。

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.push(i); }
alert(keys);

2
あなたの答えはすでに投稿されたものと似ているようですが、他に追加することはありますか?
VKen


7

Mozillaには、サポートされていないブラウザでそれを行う方法に関する完全な実装の詳細があります。

if (!Object.keys) {
  Object.keys = (function () {
    var hasOwnProperty = Object.prototype.hasOwnProperty,
        hasDontEnumBug = !({toString: null}).propertyIsEnumerable('toString'),
        dontEnums = [
          'toString',
          'toLocaleString',
          'valueOf',
          'hasOwnProperty',
          'isPrototypeOf',
          'propertyIsEnumerable',
          'constructor'
        ],
        dontEnumsLength = dontEnums.length;

    return function (obj) {
      if (typeof obj !== 'object' && typeof obj !== 'function' || obj === null) throw new TypeError('Object.keys called on non-object');

      var result = [];

      for (var prop in obj) {
        if (hasOwnProperty.call(obj, prop)) result.push(prop);
      }

      if (hasDontEnumBug) {
        for (var i=0; i < dontEnumsLength; i++) {
          if (hasOwnProperty.call(obj, dontEnums[i])) result.push(dontEnums[i]);
        }
      }
      return result;
    };
  })();
}

好きなように含めることができますextensions.jsが、スクリプトスタックの最上位にあるファイルに含めることもできます。


MDNの実装は、すでに回答として提供されているAndy Eに基づいています。
outis

5

使用する Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keysObject.getOwnPropertyNamesを得ることができない非列挙のプロパティを。列挙できないプロパティでも機能します。

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]


4

ほとんどすべてのプロジェクトでunderscore.jsを使用しているので、次のkeys関数を使用します。

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

その出力は次のようになります。

['name', 'hello']

これは、しばしば使用されるJavaScriptの機能のためのツールセットのライブラリです:underscorejs.org
schmijos

4

受け入れられた答えに基づいて構築します。

オブジェクトに呼び出したいプロパティがある場合は、.properties()と言います。

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}

0

解決策は私のケースとクロスブラウザで機能します:

var getKeys = function(obj) {
    var type = typeof  obj;
    var isObjectType = type === 'function' || type === 'object' || !!obj;

    // 1
    if(isObjectType) {
        return Object.keys(obj);
    }

    // 2
    var keys = [];
    for(var i in obj) {
        if(obj.hasOwnProperty(i)) {
            keys.push(i)
        }
    }
    if(keys.length) {
        return keys;
    }

    // 3 - bug for ie9 <
    var hasEnumbug = !{toString: null}.propertyIsEnumerable('toString');
    if(hasEnumbug) {
        var nonEnumerableProps = ['valueOf', 'isPrototypeOf', 'toString',
            'propertyIsEnumerable', 'hasOwnProperty', 'toLocaleString'];

        var nonEnumIdx = nonEnumerableProps.length;

        while (nonEnumIdx--) {
            var prop = nonEnumerableProps[nonEnumIdx];
            if (Object.prototype.hasOwnProperty.call(obj, prop)) {
                keys.push(prop);
            }
        }

    }

    return keys;
};
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.