オブジェクトのプロパティを反復処理する


2040

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(propt + ': ' + obj[propt]);
}

変数proptはオブジェクトのプロパティをどのように表しますか?組み込みのメソッドやプロパティではありません。オブジェクトのすべてのプロパティが表示されるのはなぜですか?


11
if (typeof(obj[propt]) === 'object') {/ *もう一度やり直してください* /}
noob

13
さて、この質問を本当に申し訳ありません。私はループが何であるかを知っています。「オブジェクトのプロパティをループする」に頭を悩ませることはできませんでした。また、彼らは私に「JavaScriptステップバイステップ2ndエディション-学校でのスティーブシューリング
Rafay

242
これは初心者向けのすばらしい質問です。私は他の言語で15年の専門的な経験を持っていると付け加えます、そして私はこの答えが必要でした。できれば2000をプラスします。
Nathan C. Tresch 2013

60
クレイジーですが、これを行う方法の構文を再学習するために、私は何年もの間数か月ごとにこのページにアクセスしています。私はこれを行う方法を覚えておくのに気にしません...私はこのページが常にここにあることを覚えています。
HDave 2015

14
これは、StackOverflowで見た中で最も奇妙なページです。質問を注意深く読んだ場合、実際に尋ねられていることに答えようとするのは1つの回答だけであり、スコアは-6です。受け入れられた最高得点の答えは、答えないだけでなく、単に間違っています。

回答:


2426

プロパティを反復処理するには、次の追加hasOwnPropertyチェックが必要です。

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

オブジェクトのプロトタイプには、技術的にはオブジェクトの一部であるオブジェクトの追加プロパティが含まれているため、これは必要です。これらの追加プロパティは基本オブジェクトクラスから継承されますが、依然としてのプロパティですobj

hasOwnProperty これがこのクラスに固有のプロパティであり、基本クラスから継承されたプロパティではないかどうかを確認するだけです。


hasOwnPropertyオブジェクト自体を介して呼び出すことも可能です。

if (obj.hasOwnProperty(prop)) {
    // do stuff
}

ただし、オブジェクトに同じ名前の無関係なフィールドがある場合、これは失敗します。

var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo');  // TypeError: hasOwnProperty is not a function

そのため、Object.prototype代わりに呼び出す方が安全です。

var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo');  // true

21
@BT Mozillaのドキュメントによれば、「オブジェクト自体にアタッチされているプロパティだけを考慮し、プロトタイプは考慮しない場合は、 getOwnPropertyNamesを使用するか、hasOwnPropertyチェックを実行します(propertyIsEnumerableも使用できます)。」
davidmdem 2013

3
正確に何を呼ぶのobject.hasOwnProperty()ですか?propertyどんな価値があるという事実は、その中にあることを意味しobjectませんか?
Alex S 14

6
なぜなら、オブジェクトのプロトタイプであるAlex Sには、技術的にオブジェクトの一部であるオブジェクトの追加プロパティが含まれているからです。これらは基本オブジェクトクラスから継承されますが、プロパティのままです。hasOwnPropertyは、これがこのクラスに固有のプロパティであり、基本クラスから継承されたプロパティではないかどうかを確認するだけです。良い説明:brianflove.com/2013/09/05/javascripts-hasownproperty-method
Kyle Richter

87
ただし、Object.keys(obj)は現在、オブジェクト自体のキーを取得するためのはるかに優れたソリューションであると私は言及する必要があると思います。Mozillaのドキュメントへのリンク:developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
カイルリヒター

9
重要な情報の1つが不足しています。propertyここでは文字列ですpropertyName。そうしないと、私のようなJS初心者に混乱を招く可能性がありifます。
Neolisk

1136

JavaScript 1.8.5以降では、を使用Object.keys(obj)して、オブジェクト自体に定義されているプロパティの配列(に対してtrueを返すプロパティ)を取得できますobj.hasOwnProperty(key)

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

これはfor-inループを使用するよりも優れています(そしてより読みやすくなっています)。

これらのブラウザでサポートされています:

  • Firefox(Gecko):4(2.0)
  • クロム:5
  • Internet Explorer:9

詳細については、Mozilla Developer Network Object.keys()のリファレンス参照してください。


7
これは、今より広くサポートされています。developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/...
ドムVinyardを

3
また、古いブラウザのサポートが必要な場合は、このポリフィル
KyleMit

27
この言語の構文をサポートする環境では、この方法はArray.foreachを呼び出すことができます Object.keys(myObject).forEach(function(key,index) { //key = the name of the object key //index = the ordinal position of the key within the object });
トッド価格

4
@ AJ_83 forEach()から抜け出す良い方法はありません。この場合はsome()を使用し、trueを返してブレークします
Daniel Z.

11
なぜこれはfor-inより読みやすいのですか?for candidate in candidateStatus...私には読みやすいようです
ジョナ2018

309

私たちは2019年にいる女の子で、タイプする時間はあまりありません...それで、このクールで新しい空想のECMAScript 2016をやってみましょう:

Object.keys(obj).forEach(e => console.log(`key=${e}  value=${obj[e]}`));

17
これはDanny Rの回答とどのように違うのですか?
krillgar 2017年

27
これはワンライナーであり、forEachの代わりにマップを使用します。また、console.logの内容は、一部の人にとっては興味深いかもしれません。
フラン

いない作業を行いSatly、ときobj=window.performance.memory: - /などどこにfor inありません。ievar obj = window.performance.memory; for( key in obj ) console.log( 'key=' + key + ' val=' + obj[key] );
Michaelangel007

2
window.performance.memoryはchromeでのみサポートされておりObject.keys(obj)、空の配列を返します。これはとは関係ありません.map
フランクロス

で一度に複数のことを実行できるようにこのシングルライナーを再構築することを誰もがやりたくない場合はe、この要旨を投稿しました。それはちょうど、ほとんどのハッシュ実装のように、基本的だし、用途( (key) => (value) )の代わりに{ key => value }、しかし、あなたが前にそれに対処するために持っていなかった場合、それはあなたがより良い、それを視覚化助けることができる:gist.github.com/the-nose-knows/9f06e745a56ff20519707433e28a4fa8
kayleeFrye_onDeck

216

それはfor...in statementMDNECMAScript仕様)です。

「とあなたはそれを読むことができるためのすべてのプロパティ、INobjオブジェクトに各プロパティを割り当てるPROPTの順番に変数」。


1
どうもありがとうございました。私は本やグーグルを通り抜けて頭を叩いていた。
ラファイ

21
@RightSaidFredに同意、inオペレータとforのステートメントは全く関与していない、for-in文は、独自の文法の生産を表しますfor ( LeftHandSideExpression in Expression )for ( var VariableDeclarationNoIn in Expression )
CMS

2
特にこれらの人気のあるコメントがそれと矛盾しているようであるので、この答えは奇数です。
Doug Molineux 2013

9
なぜこれが答えとしてマークされているのですか?それはかなり可能性このスレッドで少なくとも役立つ1 ..です
computrius

3
あまり役に立たない答えは?OPが何を求めているかによって異なります。私が最初に質問を読んだとき、オブジェクトのプロパティを検査するために変数を使用できるメカニズムと、この答えが雄弁に説明しているメカニズム(それにもかかわらず「for-in」の誤称)について、困惑した面白そうに思えました。「なぜすべてのプロパティが表示されるのか」という質問は、OPがhasOwnPropertyを探していたが、それがわからないことを意味している可能性がありますが、これは、OPが知りたかったことであり、正しいものを誤って受け入れた可能性が高いと思います別の質問に答えます。:-)
バンピー

157

ESの最新の実装では、以下を使用できますObject.entries

for (const [key, value] of Object.entries(obj)) { }

または

Object.entries(obj).forEach(([key, value]) => ...)

値を繰り返し処理する場合は、Object.valuesを使用します。

for (const value of Object.values(obj)) { }

または

Object.values(obj).forEach(value => ...)

これは最良の解決策(object.entries ...)ですが、使用できません。:あなたは、この複数回やってみたいし、あなたの枠組みの中でそれをサポートすることができないときは、このページにポリフィルを使用することができますdeveloper.mozilla.org/nl/docs/Web/JavaScript/Reference/...
マリオ

3番目の提案は、プロパティの値のみを指定する場合に最適です。驚くばかり!
ギンツブルク2018


27

環境がES2017をサポートしている場合は、Object.entriesをお勧めします。

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`);
});

Mozillas Object.entries()のドキュメントに示されているように:

Object.entries()メソッドは?ループ内(差があるためにインループを列挙ことによって提供されるものと同じ順序で、[キー値]のペアを指定されたオブジェクト自身の列挙プロパティの配列を返しますプロトタイプチェーンのプロパティも)。

基本的にObject.entriesを使用すると、古いfor ... inループで必要な次の追加手順を省略できます。

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}

22

jqueryを使用すると、これをすぐに実行できます。

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});

1
$.each({foo:1, length:0, bar:2}, function(k,v){console.log(k,v)})$ .eachはオブジェクトには適しいません。オブジェクトにたまたまlengthプロパティがあり、その値が偶然ゼロである場合、オブジェクト全体が空の配列であるかのように扱われます。
ボブスタイン

これがバグを誘うアプローチであると私が考える理由の詳細
ボブスタイン

21

ドミニクの答えは完璧です。読む方がわかりやすいので、私はそのようにするのが好きです。

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}

Object大文字のoを使用する必要がありますが、違いますか?
ジョナサン

18

上記の回答は、それがオブジェクトであることを確認した後、forループ内で何を行うかを説明しないため、少し迷惑です。直接アクセスすることはできません!実際には、OBJに適用する必要があるキーのみが提供されます。

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

これはすべてECMA5安全です。Rhinoのような不完全なJSバージョンでも動作します;)


15

ES2015の使用法を追加Reflect.ownKeys(obj)し、イテレーターを介してプロパティを反復します。

例えば:

let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };

によって反復することができます

// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));

オブジェクトのキーの値を直接反復処理する場合は、iteratorJavaSciptsの文字列、配列、型付き配列、MapおよびSetのデフォルトのイテレータと同様に、を定義できます。

JSは、デフォルトの反復子プロパティを介して反復を試みますSymbol.iterator。これは、として定義する必要があります。

すべてのオブジェクトを反復処理したい場合は、オブジェクトのプロトタイプとして追加できます。

Object.prototype[Symbol.iterator] = function*() { 
    for(p of Reflect.ownKeys(this)){ yield this[p]; }
}

これにより、for ... ofループでオブジェクトの値を反復処理できます。次に例を示します。

for(val of obj) { console.log('Value is:' + val ) }

注意:この回答を書いている時点(2018年6月)では、他のすべてのブラウザー(IEを除く)がジェネレーターとfor...of反復をサポートSymbol.iterator


あなたは実際にはOPの質問に答えていませんが、これは私にとって非常に役に立ちましたが、Reflectについてはまだ知りませんでした。
ミシエル

15
if(Object.keys(obj).length) {
    Object.keys(obj).forEach(key => {
        console.log("\n" + key + ": " + obj[key]);
    });
}

// *** Explanation line by line ***

// Explaining the bellow line
// It checks if obj has at least one property. Here is how:
// Object.keys(obj) will return an array with all keys in obj
// If there is no keys in obj, it will return empty array = []
// Then it will get it's length, if it has at least one element,
// it's bigger than 0 which evaluates to true and the bellow 
// code will be executed.
// Else means it's length = 0 which evaluates to false
// NOTE: you can use Object.hasOwnProperty() instead of Object.keys(obj).length
if(Object.keys(obj).length) {

    // Explaining the bellow line
    // Just like in the previous line, this returns an array with
    // all keys in obj (because if code execution got here, it means 
    // obj has keys.) 
    // Then just invoke built-in javascript forEach() to loop
    // over each key in returned array and calls a call back function 
    // on each array element (key), using ES6 arrow function (=>)
    // Or you can just use a normal function ((key) { blah blah }).
    Object.keys(obj).forEach(key => {

        // The bellow line prints out all keys with their 
        // respective value in obj.
        // key comes from the returned array in Object.keys(obj)
        // obj[key] returns the value of key in obj
        console.log("\n" + key + ": " + obj[key]);
    });
}

3
こんにちは。コードだけでは役に立たない場合は、回答に関する情報を追加してください。
Nicolas

こんにちは@Nicolas私はコードに行ごとの説明を追加しました。それでも不明な点がある場合は
お知らせください

forEach 空の値をスキップするので、ifを削除してObject.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`));、Frank Rothの答えと同じようにすることができます。
Darkproduct

12

for ... inループは、forループに似ているため、オブジェクトの各プロパティを表します。次のようにfor ... inループでプロパティを定義しました。

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

for ... inループは、オブジェクトの列挙可能なプロパティを反復処理します。定義する変数、またはfor ... inループに入れる変数は、反復する次のプロパティに移動するたびに変化します。for ... inループの変数はキーを反復処理しますが、その値はキーの値です。例えば:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

変数が変数の値とどのように異なるかがわかります。対照的に、for ... ofループはその逆です。

これがお役に立てば幸いです。


11
let obj = {"a": 3, "b": 2, "6": "a"}

Object.keys(obj).map((item) => {console.log("item", obj[item])})

// a
// 3
// 2

1
他のコメントで述べたように、反復ごとにコードブロックを呼び出した結果を含む新しい配列を返すことを目的としているためforEach、ここがより適切ですmap。ただし、関心があるのは各反復の副作用のみであり、戻り値ではないので、新しい配列は必要ありませんmap
ダニー


10

Lodashを使用できます。ドキュメント

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});

10
なぜこの「答え」には10の賛成票があるのですか。それは完全に質問に答えることに失敗します。私は平均的なJS開発者の知性に対する信頼を失い始めています。
developerbmw

1
@developerbmw ES6の機能を使用する方が正しいことを理解していますが、1年前に回答しました。少し時間がありましたら、私たちとあなたの考えを共有してください。
viktarpunko 2017年

1
アイデアは、ユーザーにページに10000行のライブラリを追加するように勧めるのではなく、ネイティブメソッドに集中することです。私を誤解しないでください、私はLodashを使うのが好きですが、それのための時間と場所があり、それはこれではありません。

9

あなたのforループは、オブジェクトのすべてのプロパティを反復処理されますobjproptforループの最初の行で定義されています。objオブジェクトのプロパティの名前である文字列です。ループの最初の反復では、propt「名前」になります。


9

JavaScriptのオブジェクトはプロパティのコレクションであるため、for eachステートメントでループできます。

objキーバリューコレクションと考える必要があります。


!これらの「プロパティのリスト」はキーとして名前を持つことができるという重要な違いがありますが、通常のJS配列はキーとしてのみ数値を持つことができます。
Qqwy

9

今日では、Symbol.iteratorメソッドを追加するだけで、標準のJSオブジェクトを反復可能なオブジェクトに変換できます。次に、for ofループを使用してその値に直接アクセスするか、オブジェクトに対して拡散演算子を使用することもできます。涼しい。どうやって作るのか見てみましょう:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);


1
それをする興味深い方法。function*発見してくれてありがとう!
ベンジ2017年

5

ノードを実行している場合、私はお勧めします:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});

5

最高評価の答えは正しいですが、これは別の使用例です。つまり、オブジェクトを反復していて、最後に配列を作成したい場合です。使用する.map代わりにforEach

const newObj = Object.keys(obj).map(el => {
    //ell will hold keys 
   // Getting the value of the keys should be as simple as obj[el]
})

4

また、再帰的な方法を追加します:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

使用法:

iterate({ foo: "foo", bar: { foo: "foo"} }); 

1
@faiz-私のコメントを参照してください。循環参照を持つオブジェクトを繰り返し歩くときに無限ループに
陥るのを防ぐ

3

for..inループが行うことは、新しい変数(var someVariable)を作成し、指定されたオブジェクトの各プロパティをこの新しい変数(someVariable)に1つずつ格納することです。したがって、ブロック{}を使用すると、反復できます。次の例を考えてみましょう。

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet

単純さを考えると、これを支持しています。私のユースケースでは、オブジェクトのすべての属性をチェックして、危険な値(NaN、null、未定義)を確認する必要があります(これらはグラフ上の点であり、これらの値はグラフの描画を妨げました)。名前の代わりに値を取得するには、ループで次のようにしますobj[someVariable]。おそらく、それがあまりにも多く投票された理由は、それが再帰的ではないためです。したがって、高度に構造化されたオブジェクトがある場合、これは適切なソリューションではありません。
キャサリンオズボーン

@KatharineOsborneまたはおそらく次のフレーズが少し不可解なためです:「したがって、ブロック{}を使用する場合、反復することができます。」コードはテキストだけではありません。
bvdb

3

ここでは、各ノードを繰り返し、意味のあるノード名を作成しています。あなたが気づいたら、instanceOf ArrayとinstanceOf Objectはほとんど同じことをします(私のアプリケーションでは、私は異なるロジックを与えています)

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

注-私はOndrej Svejdarの回答に触発されました。しかし、このソリューションはパフォーマンスが向上し、あいまいさが少なくなります


3

基本的に、オブジェクトの各プロパティをループ処理します。

JSFiddle

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);

obj(prop)<
-TypeError

@le_m悪い。私は誤ってhasOwnProperty属性を削除する必要があります。これで動作するはずです。
HovyTech 2016年

2

JavaScriptとは意図が異なる可能性があるため、上記の回答に加えたいと思います。JSONオブジェクトとJavascriptオブジェクトは異なるものであり、上記で提案されたソリューションを使用してJSONオブジェクトのプロパティを反復処理すると、驚かれる場合があります。

次のようなJSONオブジェクトがあるとします。

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

「プロパティ」を繰り返す間違った方法:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

and およびandのプロパティを繰り返し処理するとき01、コンソールのログ、などが表示されるのに驚くかもしれません。prop1prop2prop3_1。これらのオブジェクトはシーケンスであり、シーケンスのインデックスはJavaScriptでのそのオブジェクトのプロパティです。

JSONオブジェクトのプロパティを再帰的に反復するより良い方法は、最初にそのオブジェクトがシーケンスであるかどうかを確認することです。

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}

1

受け入れられた回答をさらに絞り込むには、var object = Object.create(null)thenでオブジェクトをインスタンス化するとobject.hasOwnProperty(property)TypeErrorがトリガーされることに注意してください。安全のために、次のようにプロトタイプから呼び出す必要があります。

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}

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