[javascript] JavaScript 객체를 반복하거나 열거하는 방법

다음과 같은 JavaScript 객체가 있습니다.

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

지금은 모든을 통해 루프를 원하는 p요소 ( p1, p2, p3…) 그리고 자신의 키와 값을 얻는다. 어떻게해야합니까?

필요한 경우 JavaScript 객체를 수정할 수 있습니다. 내 궁극적 인 목표는 일부 키 값 쌍을 반복하는 것이며 가능한 경우을 사용하지 않기를 원합니다 eval.



답변

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 () 대안으로 :

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

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

사용주의 for-of대신을 for-in, 그것은 명명 된 속성에 정의되지 않은, 그리고 반환됩니다 사용하지 않을 경우 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}`);
}


답변

인 ECMAScript 5에서, 당신은 결합 할 수 Object.keys()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, destructuring 및을 결합 할 수 있습니다 Object.entries.

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

모두 Object.keys()Object.entries()A와 같은 순서로 반복 처리 특성 for...in루프 하지만 프로토 타입 체인을 무시 . 객체 자체의 열거 가능한 속성 만 반복됩니다.


답변

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
}


답변

객체를 반복하는 대체 방법에 대해 언급하지 않으면 질문이 완료되지 않습니다.

오늘날 많은 잘 알려진 JavaScript 라이브러리는 컬렉션, 즉 배열 , 객체배열과 유사한 객체 를 반복하는 고유 한 메소드를 제공 합니다 . 이 방법은 사용하기 편리하며 모든 브라우저와 완전히 호환됩니다.

  1. jQuery로 작업하는 경우 jQuery.each()method를 사용할 수 있습니다 . 객체와 배열을 완벽하게 반복하는 데 사용할 수 있습니다.

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
  2. 에서 Underscore.js 당신은 방법을 찾을 수 있습니다 _.each()제공된 기능에 차례로 각각 산출 요소의 목록을 반복 할 때, (에서 인수의 순서에주의 iteratee의 기능을!)

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
  3. Lo-Dash 는 객체 속성을 반복하는 몇 가지 방법을 제공합니다. 기본 _.forEach()(또는 별명 _.each())은 객체와 배열을 반복하는 데 유용하지만 (!) length속성이있는 객체 는 배열처럼 취급 되며이 동작을 피하기 위해 사용 _.forIn()_.forOwn()메서드를 제안 합니다 (이들도 value먼저 인수가 있음).

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

    _.forIn()을 반복 자신의 상속 객체의 열거 속성, 동안 _.forOwn()반복 만 이상 자신의 객체의 속성 (기본적으로에 대해 확인 hasOwnProperty기능). 간단한 객체와 객체 리터럴의 경우 이러한 방법 중 하나가 잘 작동합니다.

일반적으로 설명 된 모든 메소드는 제공된 오브젝트와 동일한 동작을 갖습니다. 기본 for..in루프를 사용하는 것 외에도 일반적으로 와 같은 추상화보다 빠릅니다jQuery.each() . 이러한 방법은 사용하기가 훨씬 쉽고 코딩이 덜 필요하며 오류 처리 기능이 향상됩니다.


답변

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의 compat 테이블에서 볼 수있는 브라우저 지원

오래된 브라우저의 경우 간단 하고 완전한 폴리 필이 있습니다

UPD :

이 질문에서 가장 인기있는 모든 경우에 대한 성능 비교 perfjs.info:

객체 리터럴 반복


답변

머리말:

  • 객체 속성은 소유 하거나 (속성이 객체 자체에 있음) 상속 될 수 있습니다. 아닌 프로토 타입 중 하나).
  • 객체 속성은 열거 가능 또는 열거 불가능 . 열거 할 수없는 속성은 많은 속성 열거 / 배열에서 제외됩니다.
  • 속성 이름은 문자열 또는 기호 일 수 있습니다. 이름이 Symbol 인 속성은 많은 속성 열거 / 배열에서 제외됩니다.

2018 년에는 객체의 속성을 반복하는 옵션이 있습니다 (일부 예제는 목록을 따릅니다).

  1. for-in[ MDN , spec ] — 상속 된 속성 (이름이 문자열 인 속성 포함)을 포함 하여 객체의 열거 가능한 속성 이름을 반복하는 루프 구조
  2. Object.keys[ MDN , spec ] — 이름이 문자열 인 객체 자체열거 가능한 속성의 이름 배열을 제공하는 함수 입니다.
  3. Object.values[ MDN , 사양 ] – 함수는 배열 제공 객체의의 고유의 , 열거 속성.
  4. Object.entries[ MDN , spec ] — 객체 자체열거 가능한 속성 의 이름 값 배열을 제공하는 함수입니다 (배열의 각 항목은 배열입니다 ).[name, value]
  5. Object.getOwnPropertyNames[ MDN , spec ] — 이름이 문자열 인 객체 자체 속성 (열거 불가능한 속성) 의 이름 배열을 제공하는 함수 입니다.
  6. Object.getOwnPropertySymbols[ MDN , spec ] — 이름이 Symbols 인 객체 자체 속성 (열거 불가능한 속성) 의 이름 배열을 제공하는 함수 입니다.
  7. Reflect.ownKeys[ MDN , 사양 ] – 객체의 이름의 배열을 제공하는 기능을 스스로 그 이름 문자열 또는 기호 여부 속성 (심지어 비 열거 것들).
  8. 당신이 원하는 경우 모든 비 열거 상속 포함한 객체의 속성,의를, 당신은 루프를 사용할 필요가 Object.getPrototypeOf[ MDN , 사양 ] 및 사용 Object.getOwnPropertyNames, Object.getOwnPropertySymbols또는 Reflect.ownKeys(이 답변의 하단에있는 예) 각각의 프로토 타입 체인에있는 객체.

그들 모두 제외와 함께 for-in, 당신은 (배열에 구조를 루핑 어떤 종류의 사용하십시오 for, for-of, forEach, 등).

예 :

for-in:

Object.keys ( for-of루프를 사용하지만 모든 루핑 구문을 사용할 수 있습니다) :

Object.values:

Object.entries:

Object.getOwnPropertyNames:

Object.getOwnPropertySymbols:

Reflect.ownKeys:

상속 불가능한 속성 을 포함한 모든 속성 :


답변

다음과 같이 반복 할 수 있습니다.

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

참고 key속성 값에 적용되지 않습니다, 그냥 인덱스 값입니다.