해시 키를 찾는 방법?


192

나는 자바 스크립트 객체에서 해시로 두 배를 알고 있지만 키를 얻는 내장 함수를 찾을 수 없었습니다.

var h = {a:'b',c:'d'};

나는 같은 것을 원한다

var k = h.keys() ; // k = ['a','c'];

항목을 반복하고 반환하는 배열에 키를 추가하는 함수를 직접 작성하는 것이 간단하지만 표준 깔끔한 방법이 있습니까?

나는 그것이 놓친 간단한 내장 기능이어야한다고 생각하지만 그것을 찾을 수 없습니다!


나는 자바 스크립트로 뛰어 들지만이 게시물이 도움이 될 수 있습니다. dean.edwards.name/weblog/2006/07/enum
Jason Saldo


1
키에서 값을 얻는 방법은 무엇입니까? 또한 해시의 키 수를 가져옵니다.
zero_cool

2017 년 답변 : Object.keys (h) Object.values ​​(h)
losty

답변:


274

Object.keys이 작업을 수행하는 최신 JavaScript (ECMAScript 5) 기능 이 있습니다.

var obj = { "a" : 1, "b" : 2, "c" : 3};
alert(Object.keys(obj)); // will output ["a", "b", "c"]

호환성 세부 정보는 여기에서 확인할 수 있습니다 .

모질라 사이트 이전 버전과의 호환성에 대한 미리보기도 있습니다 :

if(!Object.keys) Object.keys = function(o){
   if (o !== Object(o))
      throw new TypeError('Object.keys called on non-object');
   var ret=[],p;
   for(p in o) if(Object.prototype.hasOwnProperty.call(o,p)) ret.push(p);
   return ret;
}

이것이 더 자연스럽지 않습니까? if(!Object.prototype.keys) Object.prototype.keys = function() { if (this !== Object(this)) throw new TypeError('Object.keys called on non-object'); var ret = [], p; for (p in this) if (Object.prototype.hasOwnProperty.call(this, p)) ret.push(p); return ret; } var x = { a: { A: 1, B: 2, C: 3 }, b: { A: 10, B: 20 } }; alert(x.a.keys());
ekkis

2
내가 알고있는 것처럼이 Object.prototype.keyskeys때문에 모든 개체, 개체의 모든 하위 클래스에 사용할 수 있습니다. OOP를 사용하려고 할 때 아마도 원할 것입니다. 어쨌든 이것은 실제로 요구 사항에 달려 있습니다.
Ivan Nevostruev

1
mootools를 사용하는 경우 모든 브라우저에서 Object.keys ()를 사용할 수 있어야합니다.
theeper

각도 템플릿에서 이것을 사용할 것이 있습니까? 부분적으로는 작동하지 않습니다.
Jay Shukla

코드 샘플과 함께 별도의 질문 으로이 질문을해야한다고 생각합니다.
Ivan Nevostruev

80

클라이언트 브라우저와의 큰 호환성을 요구하는 프로덕션 코드의 경우 여전히 Object.keys구형 브라우저에서 shim으로 Ivan Nevostruev의 대답을 제안 합니다. 그러나 ECMA의 새로운 defineProperty기능을 사용하여 요청 된 정확한 기능을 얻을 수 있습니다.

ECMAScript 5 기준-Object.defineProperty

ECMA5부터는 열거 할 수 Object.defineProperty()없는 속성을 정의 하는 데 사용할 수 있습니다 . 현재 호환성은 여전히 아쉬운 점이 많이있다, 그러나 이것은 결국 모든 브라우저에서 사용 가능하게해야합니다. (특히 IE8과의 비 호환성에 주목하십시오!)

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    var keys = [];
    for(var i in this) if (this.hasOwnProperty(i)) {
      keys.push(i);
    }
    return keys;
  },
  enumerable: false
});

var o = {
    'a': 1,
    'b': 2
}

for (var k in o) {
    console.log(k, o[k])
}

console.log(o.keys())

# OUTPUT
# > a 1
# > b 2
# > ["a", "b"]

그러나 ECMA5가 이미 추가되었으므로 다음 Object.keys을 사용할 수도 있습니다.

Object.defineProperty(Object.prototype, 'keys', {
  value: function keys() {
    return Object.keys(this);
  },
  enumerable: false
});

원래 답변

Object.prototype.keys = function ()
{
  var keys = [];
  for(var i in this) if (this.hasOwnProperty(i))
  {
    keys.push(i);
  }
  return keys;
}

편집 : 이 답변은 잠시 동안 있었으므로 위의 내용을 그대로 두겠습니다. 이것을 읽는 사람은 아래 Ivan Nevostruev의 답변을 읽어야합니다.

프로토 타입 함수를 열거 할 수 없도록하는 방법은 없으므로 사용하지 않는 for-in 루프에서 항상 시작됩니다 hasOwnProperty. Object의 프로토 타입을 확장하는 것이 그렇게 복잡하지 않은 경우에도 여전히이 답변이 이상적이라고 생각합니다.


9
'hasOwnProperty'는이 객체의 프로토 타입에 대한 속성을 제외하는데, 이는 유용한 정보입니다.
ijw

2
그것이 내가 그것을 구현하게 된 방식이기 때문에 대답이 받아 들여졌지만 이것이 언어의 내장 기능이어야한다고 생각합니다.
Pat

5
전역 변수를 작성하지 않으려면 "for (var i this) ..."를 사용해야합니다.
Brad G.

5
Object.prototype을 수정하지 마십시오. 아래에 언급 한 다른 주석 작성자가 hasOwnProperty () 확인에주의하지 않는 스크립트를 쉽게 중단 할 수 있습니다. 대신 OO에 친숙하지 않은 방법을 사용하십시오. '키'기능이 없으면 정의하십시오. (Firefox와 Chrome은 OP가 원하는 것을 정확하게 수행하는 기본 키 () 기능을 구현합니다
-IE

1
for (var k in array) {} 또는 for (var k in object) 및 그 관용구와 같은 모든 일반적인 루프를 끊기 때문에 Object.prototype에 무엇이든 추가하는 것은 나쁜 생각 인 것 같습니다. -매우 일반적입니다. 예를 들어 아래 Matthew Darwin의 답변에 따르면 Google지도가 손상됩니다.
Sam Watkins

42

당신이 사용할 수있는 Object.keys

Object.keys(h)

3
ECMAScript 5에 추가되었지만 지금까지 대부분의 주요 브라우저에서 작동합니다.
Pat

33

Javascript 유틸리티 라이브러리 인 Underscore.js를 사용할 수 있습니다 .

_.keys({one : 1, two : 2, three : 3}); 
// => ["one", "two", "three"]

@Pat은 내장 함수를 찾고 있기 때문에 실제로 요청 된 것은 아니지만 흥미로운 라이브러리이지만 수정하지는 않습니다.Object.prototype
fresskoma

2
요즘에는 자체 구현을 작성하는 것보다 멋진 작은 라이브러리를 사용하는 것이 훨씬 도움이된다고 생각합니다. 어쨌든 대부분의 실제 프로젝트에서 우리는 어쨌든 Underscore 또는 동등한 라이브러리를 사용하고 있습니다. 개인적으로, 나는 Underscore와 함께 가고 싶습니다.
kumarharsh

_.keys(obj).length키가 있는지 확인하십시오.
chovy

13

내가 아는 한 이것은 당신이 할 수있는 최선입니다 ...

var keys = [];
for (var k in h)keys.push(k);

2
Object.prototype이 엉망인 경우에도 작동하지 않습니다.
Phil

4
Object.prototype과 "메시지"가 아닌 이것을 사용하는 것이 좋습니다. Object.prototype에 항목을 추가하면 모든 것이 깨지는 것 같습니다. 배열 / 객체의 키를 반복하는 것은 매우 일반적인 관용구입니다.
Sam Watkins

8

jQuery 를 사용 하면 다음과 같은 키를 얻을 수 있습니다.

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
var keys = [];
$.each(bobject, function(key,val){ keys.push(key); });
console.log(keys); // ["primary", "bg", "hilite"]

또는:

var bobject =  {primary:"red",bg:"maroon",hilite:"green"};
$.map(bobject, function(v,k){return k;});

@pimlottc 덕분에


3
이 경로로 가고 싶다면 다음을 사용하십시오 JQuery.map. $.map(h, function(v,k) { return k; });
pimlottc

6

for / in을 사용하여 객체의 속성을 반복 할 수 있다고 생각하므로 다음과 같이 할 수 있습니다.

function getKeys(h) {
  Array keys = new Array();
  for (var key in h)
    keys.push(key);
  return keys;
}

4

위의 최고 등급의 답변을 사용하고 싶었습니다.

Object.prototype.keys = function () ...

그러나 Google Maps API v3과 함께 사용하면 Google Maps가 작동하지 않습니다.

for (var key in h) ...

잘 작동합니다.


1

함수만이 아닌 요소 만 가져 오려고하면이 코드가 도움이 될 수 있습니다

this.getKeys = function() {

var keys = new Array();
for(var key in this) {

    if( typeof this[key] !== 'function') {

        keys.push(key);
    }
}
return keys;

}

이것은 HashMap 구현의 일부이며 키만 원합니다. 키 this를 포함하는 hashmap 객체입니다.

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