JavaScript 객체의 속성을 나열하는 방법은 무엇입니까?


842

따라서 객체를 생성한다고 가정 해보십시오.

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

속성 이름 목록을 검색하는 가장 좋은 방법은 무엇입니까? 즉, 다음과 같은 변수 '키'로 끝나고 싶습니다.

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

3
약간 벗어난 주제이지만 underscore.js를 사용하는 경우 :_.keys(myJSONObject)
Endy Tjahjono

답변:


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

4
누구나 조명을 켜고 싶을 때 Object의 프로토 타입에 함수를 추가하지 않는 것이 좋은 이유는 무엇입니까?
Vishwanath

2
즉, 그것에 완전히 다른 질문은 자신의의, 유래 나 구글에 여기에 빠른 검색 읽을 많음을 줄 것이다
ximi

3
for (var key in myObject) {...}기술은 브라우저 및 V8 외부의 자바 스크립트 런타임에 유용합니다. 예를 들어, 자바 스크립트 map-reduce 쿼리를 Riak에 전달할 때 Object객체가 존재하지 않으므로 Object.keys메서드를 사용할 수 없습니다.
ekillaby 2016 년

19
@slashnick "간단한 버전"은 객체의 프로토 타입 체인 ( "for ... in"을 사용하는 것처럼)의 모든 속성을 반환하지만 (ECMAScript 5.1) Object.keys메서드는 객체의 자체 속성 만 반환합니다. 나는 그것을 중요한 구별로 본다.
Martin Carel

255

으로 slashnick는 지적, 당신은 그 속성 이름에 대한 개체를 반복하는 구조 "에 대한"를 사용할 수 있습니다. 그러나 객체의 프로토 타입 체인에서 모든 속성 이름을 반복하게됩니다. 객체 자체의 속성에 대해서만 반복 하려면 Object # hasOwnProperty () 메서드를 사용할 수 있습니다 . 따라서 다음과 같은 것이 있습니다.

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

25
위의 슬래시 닉의 대답 전에 이것을 읽었기를 바랍니다. esc객체에 약 백만 개의 속성이 있었으며 대부분 사용하지 않았기 때문에 키를 누르고 15 분을 보냈 습니다. 경고가있었습니다.
Mark Henderson

다음은 Zakas 자신의 주제에 대한 훌륭한 기사입니다 : nczonline.net/blog/2010/07/27/…
Pablo Cabrera

4
LOL @MarkHenderson -하지만 다음 번에, 그냥 브라우저의 프로세스를 종료 15 분 : 낭비를 대신 다시 시작
JD 스미스

- 이와 관련된 기능 obj.getOwnPropertyNames ()이다 developer.mozilla.org/en-US/docs/JavaScript/Reference/...
스티브 굿맨

@MarkHenderson 왜 console.log를 사용하지 않습니까?
LasagnaAndroid

102

Sam Dutton이 대답하자마자이 목적을위한 새로운 방법이 ECMAScript 5th Edition에 도입되었습니다. Firefox 4 , Chrome 6, Safari 5 및 IE 9Object.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 ()에 대한 검사가 포함되어 있지 않으며 프로토 타입 체인을 통해 상속 된 속성을 반환합니다. 또한 프로토 타입 체인에서 열거 할 수없는 속성으로 인해 같은 이름을 가진 로컬로 선언 된 속성이 DontEnum 속성을 상속하는 Internet Explorer의 유명한 DontEnum 버그를 설명하지 않습니다.

Object.keys () 를 구현 하면 보다 강력한 솔루션을 얻을 수 있습니다.

편집 : 프로토 타입에 잘 알려진 kangax 와의 최근 토론에 이어 , 여기 에있는 그의 Object.forIn()기능 코드를 기반으로 DontEnum 버그에 대한 해결 방법을 구현했습니다 .


좋은 대답은 항상 JSON dict라고 가정하면 허용되는 답변이 가장 정확한 솔루션으로 남아 있다고 생각합니다. 이것은 확실히 다른 곳에서 사용하는 것입니다.
David Snabel-Caunt

1
@David Caunt : Thanks :-) 불행히도, 받아 들여진 대답은 여전히 ​​DontEnum 버그에 위배되며 JSON 객체가 "valueOf"또는 "constructor"와 같은 문자열을 키 중 하나로 가질 수있는 것을 결코 알지 못합니다. 또한의 확장명을 반복합니다 Object.prototype. 그러나 짧은 코드가 더 크고 강력한 코드보다 훨씬 매력적으로 보이는 경우가 종종 있지만,이 답변의 핵심은 Object.keys()이 코드를 지원하지 않는 브라우저에서 구현할 수있는 ECMAScript 5를 사용 하는 것입니다. 기본 버전은 이보다 훨씬 성능이 좋습니다.
Andy E

2
Andy :) 아주 훌륭합니다.이 스레드에는 아무도 언급하지 않습니다. ES5 는 객체의 열거 가능한 속성에 Object.keys해당하는 문자열 배열 만 반환 합니다. 이는 기본 (사용자 정의) 객체로 작업 할 때 중요하지 않지만 호스트 객체에서는 눈에 잘 띄어 야합니다 (지정되지 않은 호스트 객체 동작은 별도의 고통스러운 이야기이지만). ALL을 통해 열거 할 속성 (비 열거 포함), ES5는 제공 (. - 내의 compat 테이블에 지원을 참조 kangax.github.com/es5-compat-table )Object.getOwnPropertyNames
kangax

2
나는 ES5 - 심에이 솔루션을 통합 한 github.com/kriskowal/es5-shim/blob/master/es5-shim.js#L390
크리스 Kowal의

2
누군가 이것이 왜 구현 Object.keys(stuff)되지 않았 는지 설명 할 수 있습니까 stuff.keys()?
Blazemonger

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/


또한 크롬 개발 도구의 콘솔, 방화범 등의 키 ()를 체크 아웃
샘 더튼에게


28

Object.getOwnPropertyNames(obj)

이 함수는로 표시되는 속성 외에 열거 할 수없는 속성도 표시합니다 Object.keys(obj).

JS에서 모든 속성에는 boolean을 포함하여 몇 가지 속성이 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

1
+1 비슷한 것을 만들려는 의도로 여기에 왔기 때문에 +1입니다.
Camilo Martin


@Kiquenet 나는 이와 같은 것을 만들고 싶을 때마다 일반 객체 관리자를 위해 정착했습니다 .HTML로 렌더링하려면 npm 모듈 과 같은 것이 있습니다. 솔직히 말해서 나는 그 이미지 위에있는 것보다 더 나은 것을 원했지만 개념화하지 못했습니다. 인스펙터에서 객체를 찾아보기는 쉽지 않지만 임의의 객체 (예 : 객체 배열을 열이있는 테이블로 정렬)에서 의미를 추론하려고 시도하는 휴리스틱은 항상 실제로 작동하지는 않습니다.
카밀로 마틴

에 대해 무엇을 것 예쁜 자바 스크립트를 인쇄 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

js 1.8을 지원하는 브라우저에서 :

[i for(i in obj)]

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']

그것은 자주 사용되는 자바 스크립트 기능을위한 도구 세트 라이브러리입니다 : underscorejs.org
schmijos

4

허용 된 답변을 바탕으로합니다.

Object에 .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.