3332

次のような JavaScript オブジェクトがあります。

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

ここで、すべてのp要素 ( p1p2p3...) をループして、それらのキーと値を取得します。どうやってやるの?

必要に応じて JavaScript オブジェクトを変更できます。私の最終的な目標は、いくつかのキーと値のペアをループすることであり、可能であればeval.

4

43 に答える 43

4917

for-in他の人が示すように、ループを使用できます。ただし、取得するキーがオブジェクトの実際のプロパティであり、プロトタイプからのものではないことも確認する必要があります。

スニペットは次のとおりです。

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}

Object.keys() 代替の for-of:

var p = {
    0: "value1",
    "b": "value2",
    key: "value3"
};

for (var key of Object.keys(p)) {
    console.log(key + " -> " + p[key])
}

for-ofの代わりに を使用していることに注意してください。使用しfor-inない場合、名前付きプロパティで undefined が返され、Object.keys()プロトタイプ チェーン プロパティ全体を使用せずに、オブジェクト自体のプロパティのみを使用できるようになります。

新しいObject.entries()方法を使用する:

注:この方法は、Internet Explorer ではネイティブにサポートされていません。古いブラウザには Polyfill の使用を検討してください。

const p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (let [key, value] of Object.entries(p)) {
  console.log(`${key}: ${value}`);
}
于 2009-03-26T06:12:13.807 に答える
1267

Object.keys()ECMAScript 5 では、とを組み合わせることができますArray.prototype.forEach()

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ECMAScript 6 では以下が追加されますfor...of

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ECMAScript 8 はObject.entries()、元のオブジェクトの各値を検索する必要がないように追加します。

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

for...of、分解、およびを組み合わせることができますObject.entries

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

と の両方がループと同じ順序でプロパティObject.keys()を反復しますが、プロトタイプ チェーンは無視します。オブジェクト自体の列挙可能なプロパティのみが反復されます。Object.entries()for...in

于 2011-04-20T21:59:19.703 に答える
366

for-in ループを使用する必要があります

ただし、この種のループを使用する場合は十分に注意してください。プロトタイプ チェーンに沿ってすべてのプロパティがループされるためです。

したがって、for-in ループを使用する場合は、常にhasOwnPropertyメソッドを使用して、反復中の現在のプロパティが実際にチェックしているオブジェクトのプロパティであるかどうかを判断してください。

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}
于 2009-03-26T06:12:16.960 に答える
262

オブジェクトをループするための代替方法について言及しなければ、質問は完全ではありません。

現在、よく知られている JavaScript ライブラリの多くは、コレクション、つまり配列オブジェクト、および配列のようなオブジェクトを反復処理するための独自のメソッドを提供しています。これらのメソッドは使いやすく、どのブラウザとも完全に互換性があります。

  1. jQueryを使用する場合は、メソッドを使用できますjQuery.each()。オブジェクトと配列の両方をシームレスに反復するために使用できます。

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. Underscore.jsには_.each()、要素のリストを反復処理するmethodがあり、それぞれが提供された関数に順番に渡されます ( iteratee関数の引数の順序に注意してください!)。

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Dashには、オブジェクト プロパティを反復処理するためのメソッドがいくつか用意されています。Basic _.forEach()(またはエイリアス_.each()) は、オブジェクトと配列の両方をループするのに役立ちますが、(!)lengthプロパティを持つオブジェクトは配列のように扱われ、この動作を回避するには、メソッド_.forIn()_.forOwn()メソッドを使用することをお勧めします (これらにもvalue引数が最初に来ます)。

    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn()オブジェクトの独自および継承された列挙可能なプロパティを反復処理しますが、オブジェクトの独自の_.forOwn()プロパティのみを反復処理します (基本的に関数に対してチェックします)。単純なオブジェクトとオブジェクト リテラルの場合、これらのメソッドはどれも正常に機能します。hasOwnProperty

通常、説明されているすべてのメソッドは、提供されたオブジェクトに対して同じ動作をします。通常、ネイティブfor..inループを使用すると、 などのどの抽象化よりも高速jQuery.each()になります。これらのメソッドは、かなり使いやすく、必要なコーディングが少なく、エラー処理が優れています。

于 2013-01-20T17:58:26.900 に答える
58

次のように繰り返すことができます:

for (var key in p) {
  alert(p[key]);
}

プロパティの値を取得しないことに注意してくださいkey。これは単なるインデックス値です。

于 2009-03-26T06:05:01.797 に答える
56

ECMAScript 5 では、リテラルの反復フィールドに新しいアプローチがあります -Object.keys

MDNで参照できる詳細情報

私の選択は、現在のバージョンのブラウザー (Chrome30、IE10、FF25) でのより高速なソリューションとして以下のとおりです。

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

jsperf.comで、このアプローチのパフォーマンスをさまざまな実装と比較できます。

Kangax の互換表で確認できるブラウザのサポート

古いブラウザの場合、シンプル完全なポリフィルがあります

更新:

この質問で最も一般的なすべてのケースのパフォーマンス比較perfjs.info:

オブジェクトリテラル反復

于 2013-11-16T19:59:49.307 に答える
33

es2015 の人気がますます高まっているため、[key, value]ペアをスムーズに反復するためのジェネレーターとイテレーターの使用を含むこの回答を投稿しています。Rubyなどの他の言語でも可能です。

ここにコードがあります:

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
  [Symbol.iterator]: function*() {
    for (const i of Object.keys(this)) {
      yield [i, this[i]];
    }
  }
};

for (const [k, v] of MyObject) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

イテレーターとジェネレーターの実行方法に関するすべての情報は、開発者の Mozilla ページで見つけることができます。

それが誰かを助けたことを願っています。

編集:

ES2017 には、オブジェクト内のペアのObject.entries繰り返しを[key, value]さらに簡単にするものが含まれます。ts39ステージ情報によると、それが標準の一部になることが現在わかっています。

答えを更新して、今よりもさらに新鮮にする時が来たと思います。

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

MDNページで使用方法の詳細を確認でき ます

于 2016-08-27T09:06:28.797 に答える
32
for(key in p) {
  alert( p[key] );
}

注: 配列に対してこれを行うことができますが、lengthおよび他のプロパティに対しても反復処理を行います。

于 2009-03-26T06:04:10.053 に答える
21

ここですべての回答を調べた後、json オブジェクトがクリーンであるため、自分の使用に hasOwnProperty は必要ありません。JavaScript 処理を追加しても意味がありません。これは私が使用しているすべてです:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}
于 2011-08-18T20:50:22.940 に答える
20

プロトタイプチェーンプロパティをスキップする必要があるforEach()を使用したプロトタイプ経由:

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3
于 2012-12-09T05:05:51.860 に答える
18

これらの回答の興味深い人々は両方に触れましたが、それらを組み合わせることはObject.keys()ありませんでした:for...of

var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
    console.log(key + ':' + map[key]);

イテレータではないためだけではできませんfor...of。また、ingは醜い/非効率的です。ほとんどの人が(チェックの有無にかかわらず) を控えていることをうれしく思います.Objectfor...index.forEach()Object.keys()
for...in.hasOwnProperty()


通常のオブジェクトの関連付けを繰り返すことができます! Mapfor...of
Chrome と FF で動作する派手なDEMOを直接使用して s と同じように動作します(ES6 のみを想定しています)。

var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
    //key:value
    console.log(pair[0] + ':' + pair[1]);

//or
for (let [key, value] of ordinaryObject)
    console.log(key + ':' + value);

以下に私のシムを含める限り:

//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
    var keys = Object.keys(this)[Symbol.iterator]();
    var obj = this;
    var output;
    return {next:function() {
        if (!(output = keys.next()).done)
            output.value = [output.value, obj[output.value]];
        return output;
    }};
};

優れたシンタックス シュガーを持たない実際の Map オブジェクトを作成する必要はありません。

var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
    console.log(pair[0] + ':' + pair[1]);

実際、この shim を使用すると、Map の他の機能を (それらをすべて shimming せずに) 利用したいが、きちんとしたオブジェクト表記法を使用したい場合は、オブジェクトが反復可能になったため、それから Map を作成できます!

//shown in demo
var realMap = new Map({well:'hello', there:'!'});

shim を好まない、または一般的にいじるのが好きでない人は、関数を window で自由に作成して、 thenprototypeのように呼び出してください。getObjIterator()

//no prototype manipulation
function getObjIterator(obj) {
    //create a dummy object instead of adding functionality to all objects
    var iterator = new Object();

    //give it what the shim does but as its own local property
    iterator[Symbol.iterator] = function() {
        var keys = Object.keys(obj)[Symbol.iterator]();
        var output;

        return {next:function() {
            if (!(output = keys.next()).done)
                output.value = [output.value, obj[output.value]];
            return output;
        }};
    };

    return iterator;
}

これで、通常の関数として呼び出すことができます。他に影響はありません

var realMap = new Map(getObjIterator({well:'hello', there:'!'}))

また

for (let pair of getObjIterator(ordinaryObject))

それがうまくいかない理由はありません。

未来へようこそ。

于 2016-06-28T09:42:22.837 に答える
16

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " = " + p[key]);
    }
}
<p>
  Output:<br>
  p1 = values1<br>
  p2 = values2<br>
  p3 = values3
</p>

于 2012-02-21T11:22:41.743 に答える
10

オブジェクトを繰り返し処理する別の方法を次に示します。

   var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};


Object.keys(p).forEach(key => { console.log(key, p[key]) })

于 2017-12-20T04:42:57.763 に答える
7

シンプルなforEach関数をすべてのオブジェクトに追加できるため、任意のオブジェクトを自動的にループできます。

Object.defineProperty(Object.prototype, 'forEach', {
    value: function (func) {
        for (var key in this) {
            if (!this.hasOwnProperty(key)) {
                // skip loop if the property is from prototype
                continue;
            }
            var value = this[key];
            func(key, value);
        }
    },
    enumerable: false
});

「 for ... in 」メソッドが嫌いな人のために:

Object.defineProperty(Object.prototype, 'forEach', {
    value: function (func) {
        var arr = Object.keys(this);
        for (var i = 0; i < arr.length; i++) {
            var key = arr[i];
            func(key, this[key]);
        }
    },
    enumerable: false
});

これで、簡単に呼び出すことができます:

p.forEach (function(key, value){
    console.log ("Key: " + key);
    console.log ("Value: " + value);
});

他の forEach-Methods と競合したくない場合は、一意の名前を付けることができます。

于 2016-11-22T20:46:31.383 に答える
7

純粋な JavaScript を使用する場合、ループは非常に興味深いものになります。ECMA6 (New 2015 JavaScript specification) だけがループを制御できたようです。残念ながら、私がこれを書いている時点では、ブラウザーと一般的な統合開発環境 (IDE) の両方が、新しい付加機能を完全にサポートするのにまだ苦労しています。

ECMA6 以前の JavaScript オブジェクト ループは次のようになっています。

for (var key in object) {
  if (p.hasOwnProperty(key)) {
    var value = object[key];
    console.log(key); // This is the key;
    console.log(value); // This is the value;
  }
}

また、これはこの質問の範囲外であることはわかっていますが、2011 年に ECMAScript 5.1forEachで配列のみのメソッドが追加されました。これにより、基本的に配列をループする新しい改善された方法が作成されましたが、反復不可能なオブジェクトは古い冗長で紛らわしいforループのままです。しかし、奇妙なことに、この新しいforEach方法はサポートされていないためbreak、他のあらゆる種類の問題が発生しました。

基本的に 2011 年には、多くの一般的なライブラリ (jQuery、Underscore など) が再実装することを決定した以外に、JavaScript でループするための確実な方法はありません。

2015 年の時点で、任意のオブジェクト タイプ (配列と文字列を含む) をループ (および中断) するための、すぐに使える優れた方法が用意されています。レコメンデーションが主流になると、最終的に JavaScript のループは次のようになります。

for (let [key, value] of Object.entries(object)) {
    console.log(key); // This is the key;
    console.log(value); // This is the value;
}

2016 年 6 月 18 日の時点で、ほとんどのブラウザーは上記のコードをサポートしていないことに注意してください。Chrome でも、この特別なフラグを有効にする必要があります。chrome://flags/#enable-javascript-harmony

これが新しい標準になるまでは、古い方法を引き続き使用できますが、人気のあるライブラリの代替手段や、これらのライブラリを使用していない人向けの軽量の代替手段もあります.

于 2016-06-18T02:11:52.193 に答える
5

obj.hasOwnerPropertyすべてのfor ... inループ内でチェックするのではなく、これを行います。

var obj = {a : 1};
for(var key in obj){
    //obj.hasOwnProperty(key) is not needed.
    console.log(key);
}
//then check if anybody has messed the native object. Put this code at the end of the page.
for(var key in Object){
    throw new Error("Please don't extend the native object");
}
于 2015-07-09T08:22:46.417 に答える
5

ES6 では、以前の内部メソッドを公開する既知のシンボルがあります。これを使用して、このオブジェクトに対してイテレータがどのように機能するかを定義できます。

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3",
    *[Symbol.iterator]() {
        yield *Object.keys(this);
    }
};

[...p] //["p1", "p2", "p3"]

これにより、for...in es6 ループを使用した場合と同じ結果が得られます。

for(var key in p) {
    console.log(key);
}

しかし、es6 を使用して現在持っている機能を知ることは重要です!

于 2016-09-20T09:04:34.500 に答える
4

列挙不可能なプロパティも反復処理する場合は、 を使用Object.getOwnPropertyNames(obj)して、特定のオブジェクトで直接見つかったすべてのプロパティ (列挙可能かどうかに関係なく) の配列を返すことができます。

var obj = Object.create({}, {
  // non-enumerable property
  getFoo: {
    value: function() { return this.foo; },
    enumerable: false
  }
});

obj.foo = 1; // enumerable property

Object.getOwnPropertyNames(obj).forEach(function (name) {
  document.write(name + ': ' + obj[name] + '<br/>');
});

于 2015-09-12T16:31:40.660 に答える
1

これは、javascript オブジェクトをループしてデータをテーブルに入れる方法です。

<body>
<script>
function createTable(objectArray, fields, fieldTitles) {
  let body = document.getElementsByTagName('body')[0];
  let tbl = document.createElement('table');
  let thead = document.createElement('thead');
  let thr = document.createElement('tr');

  for (p in objectArray[0]){
    let th = document.createElement('th');
    th.appendChild(document.createTextNode(p));
    thr.appendChild(th);
    
  }
 
  thead.appendChild(thr);
  tbl.appendChild(thead);

  let tbdy = document.createElement('tbody');
  let tr = document.createElement('tr');
  objectArray.forEach((object) => {
    let n = 0;
    let tr = document.createElement('tr');
    for (p in objectArray[0]){
      var td = document.createElement('td');
      td.appendChild(document.createTextNode(object[p]));
      tr.appendChild(td);
      n++;
    };
    tbdy.appendChild(tr);    
  });
  tbl.appendChild(tbdy);
  body.appendChild(tbl)
  return tbl;
}

createTable([
              {name: 'Banana', price: '3.04'}, // k[0]
              {name: 'Orange', price: '2.56'},  // k[1]
              {name: 'Apple', price: '1.45'}
           ])
</script>

于 2019-02-07T05:28:47.820 に答える
-3

ES2015 以降、for ループを使用して要素に直接アクセスできます。

// before ES2015
for(var key of elements){
  console.log(elements[key]);
}


// ES2015
for(let element of elements){
  console.log(element);
}

これが誰かに役立つことを願っています。

于 2016-04-14T11:27:20.940 に答える