JavaScript 객체를 반복하는 방법은 무엇입니까?


422

JavaScript로 된 객체가 있습니다.

{
    abc: '...',
    bca: '...',
    zzz: '...',
    xxx: '...',
    ccc: '...',
    // ...
}

for속성을 얻기 위해 루프 를 사용하고 싶습니다 . 그리고 부분적으로 반복하고 싶습니다 (모든 객체 속성이 한 번에 아님).

간단한 배열을 사용하면 표준 for루프로 수행 할 수 있습니다 .

for (i = 0; i < 100; i++) { ... } // first part
for (i = 100; i < 300; i++) { ... } // second
for (i = 300; i < arr.length; i++) { ... } // last

그러나 객체로 어떻게합니까?


22
객체 속성은 순서대로 저장되지 않습니다. 객체를 반복 할 때 객체가 나타나는 순서를 보장 할 수 없습니다.
James Allardice

답변:


850

대부분의 객체에는 다음을 사용하십시오 for .. in.

for (let key in yourobject) {
  console.log(key, yourobject[key]);
}

ES6에서는 키와 값을 동시에 필요로하는 경우

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

상속 된 속성을 로깅하지 않으려면 hasOwnProperty로 확인하십시오 .

for (let key in yourobject) {
   if (yourobject.hasOwnProperty(key)) {
      console.log(key, yourobject[key]);
   }
}

hasOwnProperty간단한 객체 (예 :와 같이 만든 객체)를 사용하는 경우 키를 반복 할 때 확인할 필요가 없습니다 {}.

이 MDN 설명서 는 객체 및 해당 속성을 처리하는 방법을보다 일반적으로 설명합니다.

"청크 단위로"하려면 배열에서 키를 추출하는 것이 가장 좋습니다. 주문이 보장되지 않으므로 올바른 방법입니다. 최신 브라우저에서 사용할 수 있습니다

let keys = Object.keys(yourobject);

호환성을 높이려면 다음을 수행하는 것이 좋습니다.

 let keys = [];
 for (let key in yourobject) {      
     if (yourobject.hasOwnProperty(key)) keys.push(key);
 }

그런 다음 색인별로 속성을 반복 할 수 있습니다. yourobject[keys[i]]:

for (let i=300; i < keys.length && i < 600; i++) { 
   console.log(keys[i], yourobject[keys[i]]);
}

3
OP는 단일 루프의 모든 키가 아닌 청크로 이것을 수행하려고합니다.
pawel

예. 하나의 루프에서 전체 객체가 아닙니다.
nkuhta

2
@Cerbrus OP allready는 배열을 부분적으로 반복하는 방법을 알고 있습니다. keys주어진 코드에서 사용하면 충분합니다.
Yoshi

2
@Cerbrus 댓글을 작성하기 전에 반드시 읽어주십시오! 무엇을 분명하지 않다 ", 당신은 더 나은이 작업을 수행 할 것 더 호환되도록" ?
Denys Séguret

2
@ am05mhz 내가 말했듯이 대부분의 객체에는 쓸모가 없습니다. 그러나 전부는 아닙니다. 이것을보십시오 : jsbin.com/hirivubuta/1/edit?js,console,output
Denys Séguret

61

최신 브라우저를위한 또 다른 반복 솔루션은 다음과 같습니다.

Object.keys(obj)
  .filter((k, i) => i >= 100 && i < 300)
  .forEach(k => console.log(obj[k]));

또는 필터 기능이없는 경우 :

Object.keys(obj).forEach((k, i) => {
    if (i >= 100 && i < 300) {
        console.log(obj[k]);
    }
});

그러나 JavaScript 객체의 속성이 정렬되지 않은 것, 즉 순서가 없다는 것을 고려해야합니다.


루프를 끊으면 다음에 객체가 시작될 때부터 시작됩니다.
nkuhta

21

Object.entries당신을 사용 하면 이런 식으로 할 수 있습니다.

 // array like object with random key ordering
 const anObj = { 100: 'a', 2: 'b', 7: 'c' };
 console.log(Object.entries(anObj)); // [ ['2', 'b'],['7', 'c'],['100', 'a'] ]

Object.entries () 메소드는 주어진 객체의 자체 열거 가능 속성 [키, 값]의 배열을 반환합니다

따라서 객체를 반복하고 각 객체를 가지고 key있고 value이와 같은 것을 얻을 수 있습니다.

const anObj = { 100: 'a', 2: 'b', 7: 'c' };
Object.entries(anObj).map(obj => {
   const key   = obj[0];
   const value = obj[1];

   // do whatever you want with those values.
});

또는 이런

// Or, using array extras
Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});

참조를 위해 객체 항목에 대한 MDN 문서를보십시오


17

새로운 ES6 / ES2015 기능을 사용하면 해시를 반복하기 위해 더 이상 객체를 사용할 필요가 없습니다. 지도 를 사용할 수 있습니다 . Javascript Maps는 키를 삽입 순서대로 유지하므로 항상 해킹 인 hasOwnProperty를 확인하지 않고도 키를 반복 할 수 있습니다.

지도를 반복합니다 :

var myMap = new Map();
myMap.set(0, "zero");
myMap.set(1, "one");
for (var [key, value] of myMap) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

for (var key of myMap.keys()) {
  console.log(key);
}
// Will show 2 logs; first with "0" and second with "1"

for (var value of myMap.values()) {
  console.log(value);
}
// Will show 2 logs; first with "zero" and second with "one"

for (var [key, value] of myMap.entries()) {
  console.log(key + " = " + value);
}
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

또는 각 용도로 사용하십시오.

myMap.forEach(function(value, key) {
  console.log(key + " = " + value);
}, myMap)
// Will show 2 logs; first with "0 = zero" and second with "1 = one"

1
forEach는 선호되는 것입니다
pungggi

14

반복 할 때 키와 값 을 원하면 Object.entries 와 함께 for ... of 루프를 사용할 수 있습니다 .

const myObj = {a: 1, b: 2}

for (let [key, value] of Object.entries(myObj)) {
    console.log(`key=${key} value=${value}`)
}

// output: 
// key=a value=1
// key=b value=2

7

이를 수행하는 유일한 신뢰할 수있는 방법은 객체 데이터를 2 개의 배열, 하나는 키 및 하나는 데이터에 저장하는 것입니다.

var keys = [];
var data = [];
for (var key in obj) {
    if (obj.hasOwnProperty(key)) {
        keys.push(key);
        data.push(obj[key]); // Not necessary, but cleaner, in my opinion. See the example below.
    }
}

그런 다음 평소와 같이 배열을 반복 할 수 있습니다.

for(var i = 0; i < 100; i++){
    console.log(keys[i], data[i]);
    //or
    console.log(keys[i], obj[keys[i]]); // harder to read, I think.
}
for(var i = 100; i < 300; i++){
    console.log(keys[i], data[i]);
}

Object.keys(obj)IE 9 이상이기 때문에을 사용하지 않습니다 .


3

-> 객체 배열의 키를 사용하여 JavaScript 객체를 반복하는 경우

Object.keys(Array).forEach(key => {

 console.log('key',key)

})

1

전체 객체를 한 번에 반복하려면 for in루프를 사용할 수 있습니다 .

for (var i in obj) {
  ...
}

그러나 실제로 객체를 여러 부분으로 나누려면 할 수 없습니다. 객체의 속성이 지정된 순서대로 보장되지는 않습니다. 따라서 두 가지 해결책을 생각할 수 있습니다.

첫 번째는 이미 읽은 속성을 "제거"하는 것입니다.

var i = 0;
for (var key in obj) {
    console.log(obj[key]);
    delete obj[key];
    if ( ++i > 300) break;
}

내가 생각할 수있는 또 다른 해결책은 객체 대신 Array of Arrays를 사용하는 것입니다.

var obj = [['key1', 'value1'], ['key2', 'value2']];

그런 다음 표준 for루프가 작동합니다.


1

마지막으로 객체, 문자열, 배열, TypedArray, 맵, 세트 (모든 반복 가능)를 반복하는 통합 인터페이스가있는 편리한 유틸리티 기능을 생각해 냈습니다.

const iterate = require('@a-z/iterate-it');
const obj = { a: 1, b: 2, c: 3 };

iterate(obj, (value, key) => console.log(key, value)); 
// a 1
// b 2
// c 3

https://github.com/alrik/iterate-javascript


1

lodash- 모듈 식, 성능 및 추가 기능을 제공하는 최신 JavaScript 유틸리티 라이브러리를 사용하여 빠른 객체 반복을 시도 할 수 있습니다 .

var  users  =   {
    'fred':     { 
        'user':   'fred',
            'age':  40 
    },
    'pebbles':  { 
        'user':   'pebbles',
         'age':  1 
    }
}; 
_.mapValues(users,  function(o)  { 
    return  o.age; 
});
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
// The `_.property` iteratee shorthand.
console.log(_.mapValues(users,  'age')); // returns age property & value 
console.log(_.mapValues(users,  'user')); // returns user property & value 
console.log(_.mapValues(users)); // returns all objects 
// => { 'fred': 40, 'pebbles': 1 } (iteration order is not guaranteed)
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash-compat/3.10.2/lodash.js"></script>


1

객체 반복의 경우 일반적으로 for..in루프를 사용합니다 . 이 구조는 프로토 타입 상속을 통해 상속 된 속성을 포함하여 열거 가능한 모든 속성 을 반복합니다 . 예를 들면 다음과 같습니다.

let obj = {
  prop1: '1',
  prop2: '2'
}

for(let el in obj) {
  console.log(el);
  console.log(obj[el]);
}

그러나 for..in열거 가능한 모든 요소를 ​​반복하므로 반복을 청크로 나눌 수 없습니다. 이를 위해 내장 Object.keys()함수를 사용하여 배열에서 객체의 모든 키를 검색 할 수 있습니다 . 그런 다음 반복을 여러 for 루프로 분할하고 keys 배열을 사용하여 속성에 액세스 할 수 있습니다. 예를 들면 다음과 같습니다.

let obj = {
  prop1: '1',
  prop2: '2',
  prop3: '3',
  prop4: '4',
};

const keys = Object.keys(obj);
console.log(keys);


for (let i = 0; i < 2; i++) {
  console.log(obj[keys[i]]);
}


for (let i = 2; i < 4; i++) {
  console.log(obj[keys[i]]);
}


0
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);

1
사실은 아니야 이것은 Objects가 순서대로 있음을 의미합니다 . 그들은 아니야. If you can make sense of the sentence it worked구현 세부 사항 때문에 작동합니다. 전혀 작동하지 않을 수도 있습니다. 또한 함수와 변수를 TitleCase해서는 안됩니다. 그것은 classes입니다.
Florian Wendelborn

0

실제로 PITA는 표준 Javascript의 일부가 아닙니다.

/**
 * Iterates the keys and values of an object.  Object.keys is used to extract the keys.
 * @param object The object to iterate
 * @param fn (value,key)=>{}
 */
function objectForEach(object, fn) {
    Object.keys(object).forEach(key => {
        fn(object[key],key, object)
    })
}

참고 : 콜백 매개 변수를 (value, key)로 전환하고 API가 다른 API와 일치하도록 세 번째 객체를 추가했습니다.

이렇게 사용하세요

const o = {a:1, b:true};
objectForEach(o, (value, key, obj)=>{
    // do something
});

1
첫 번째 문장에서 당신의 진술만을 위해 찬성했습니다. 값이 첫 번째 매개 변수, 인덱스 또는 키 두 번째 매개 변수 및 개체 세 번째 매개 변수 인 경우 forEach () 배열과 비슷하게 만드는 것이 좋습니다. 그래도 lodash를 추천하는 것이 좋습니다.
계약의 말이 맞다

(값, 키) 순서에 대한 아이디어가 마음에 듭니다. Vue와 같은 라이브러리도 그렇게합니다. 객체는 컨텍스트이므로 첫 번째 매개 변수로 간주됩니다. 함수형 프로그래밍의 표준입니다.
Steven Spungin 2016 년

ECMA-262가 forEach (), map (), reduce (), filter ()를 갖는 객체로 배열을 정의하는 것이 아니라는 점에 동의합니다. 모두 [값, 색인, 배열] . JS의 객체는 또 다른 컬렉션으로 이해 될 수 있습니다. 그런 다음 이러한 방법은 [value, key | index, context]의 매개 변수로 통합됩니다 (이것은 lodash 및 밑줄이 수행하는 작업입니다). 제 생각에는이 "통합 컬렉션"프로토콜이 더 강력합니다. 또한 객체 컨텍스트 가 아닙니다this . 콜백에는 자체 컨텍스트가 있으므로 콜백에 대해 원하는대로 설정할 수 있습니다 .
계약의

아마도이 대신 작업 수신기를 사용해야했을 것입니다. 어쨌든 여전히 PITA; 어떤 순서로든 매개 변수를 환영합니다.
Steven Spungin 2016 년

오, 우리가 서로를 잘못 이해했을 수도 있습니다. 나는 항상 실제 objectForEach함수가 아닌 콜백 매개 변수와 순서에 대해 언급했습니다 . 혼란스러워서 죄송합니다.
계약이 맞습니다.

0

예. for 루프를 사용하여 객체를 반복 할 수 있습니다. 여기에 예가 있습니다

var myObj = {
    abc: 'ABC',
    bca: 'BCA',
    zzz: 'ZZZ',
    xxx: 'XXX',
    ccc: 'CCC',
}

var k = Object.keys (myObj);
for (var i = 0; i < k.length; i++) {
    console.log (k[i] + ": " + myObj[k[i]]);
}

참고 : 위에서 언급 한 예는 IE9 +에서만 작동합니다. 여기 Objec.keys 브라우저 지원을 참조 하십시오 .


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.