Wie finde ich Schlüssel eines Hash?


192

Ich weiß, dass in Javascript Objekte doppelt so viele Hashes sind, aber ich konnte keine eingebaute Funktion finden, um die Schlüssel zu erhalten

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

Ich möchte so etwas wie

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

Es ist einfach, selbst eine Funktion zu schreiben, um die Elemente zu durchlaufen und die Schlüssel zu einem Array hinzuzufügen, das ich zurückgebe. Aber gibt es eine sauberere Standardmethode, um dies zu tun?

Ich habe immer das Gefühl, dass es eine einfache eingebaute Funktion sein muss, die ich verpasst habe, aber ich kann sie nicht finden!


Ich springe gerade in Javascript, aber dieser Beitrag kann Ihnen helfen. dean.edwards.name/weblog/2006/07/enum
jason saldo

Mögliches Duplikat von Get Array der Objektschlüssel
blo0p3r

1
Was ist mit dem Abrufen der Werte von den Schlüsseln? Außerdem wird die Anzahl der Schlüssel in einem Hash ermittelt.
zero_cool

Die Antwort 2017: Object.keys (h) Object.values ​​(h)
verloren

Antworten:


274

In modernem JavaScript (ECMAScript 5) gibt es eine Funktion, Object.keysdie diese Operation ausführt:

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

Details zur Kompatibilität finden Sie hier .

Auf der Mozilla-Site gibt es auch einen Ausschnitt zur Abwärtskompatibilität:

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;
}

Wäre das nicht natürlicher gewesen? 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
Wie verstehe ich das Object.prototype.keysmacht keysfür alle Unterklassen von Object zur Verfügung, also für alle Objekte. Was Sie wahrscheinlich möchten, wenn Sie versuchen, OOP zu verwenden. Auf jeden Fall hängt dies wirklich von Ihren Anforderungen ab.
Ivan Nevostruev

1
Wenn Sie mootools verwenden, sollte Object.keys () in allen Browsern verfügbar sein.
Thepeer

Gibt es etwas, um dies in eckigen Vorlagen zu verwenden? Es funktioniert dort nicht in Teilbereichen.
Jay Shukla

Ich denke, Sie sollten dies als separate Frage mit Codebeispiel stellen.
Ivan Nevostruev

80

Für Produktionscode, der eine große Kompatibilität mit Client-Browsern erfordert, empfehle ich weiterhin Ivan Nevostruevs Antwort oben mit Shim, um dies Object.keysin älteren Browsern sicherzustellen . Mit der neuen Funktion von ECMA ist es jedoch möglich, die genaue angeforderte Funktionalität zu erhalten defineProperty.

Ab ECMAScript 5 - Object.defineProperty

Ab ECMA5 können Sie Object.defineProperty()nicht aufzählbare Eigenschaften definieren. Die aktuelle Kompatibilität lässt noch zu wünschen übrig, sollte aber irgendwann in allen Browsern verwendbar sein. (Beachten Sie insbesondere die aktuelle Inkompatibilität mit 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"]

Da ECMA5 jedoch bereits hinzugefügt wurde, können Object.keysSie auch Folgendes verwenden:

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

Ursprüngliche Antwort

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

Bearbeiten: Da es diese Antwort schon eine Weile gibt, werde ich das oben Gesagte unberührt lassen. Wer dies liest, sollte auch die Antwort von Ivan Nevostruev unten lesen.

Es gibt keine Möglichkeit, Prototypfunktionen nicht aufzählbar zu machen, was dazu führt, dass sie immer in For-In-Schleifen auftauchen, die nicht verwendet werden hasOwnProperty. Ich denke immer noch, dass diese Antwort ideal wäre, wenn die Erweiterung des Prototyps von Object nicht so chaotisch wäre.


9
'hasOwnProperty' schließt Eigenschaften für die Prototypen dieses Objekts aus, was nützlich zu wissen ist.
ijw

2
Die Antwort wurde akzeptiert, da ich sie so implementiert habe, aber ich denke, dass dies eine integrierte Funktion der Sprache sein sollte.
Pat

5
Beachten Sie, dass Sie "for (var i in this) ..." verwenden sollten, um das Erstellen einer globalen Variablen zu vermeiden.
Brad G.

5
Ich würde es vermeiden, Object.prototype zu ändern. Wie ein anderer Kommentator weiter unten erwähnt, kann dies leicht dazu führen, dass Skripte beschädigt werden, bei denen die Überprüfung von hasOwnProperty () nicht sorgfältig durchgeführt wird. Verwenden Sie stattdessen die weniger OO-freundliche Methode: Definieren Sie eine Tastenfunktion, falls diese noch nicht vorhanden ist. (Firefox und Chrome implementieren beide eine native Schlüsselfunktion (), die genau das tut, was das OP will - IE nicht)
Digitalbad

1
Es scheint eine schlechte Idee zu sein, Object.prototype etwas hinzuzufügen, da es jede normale Schleife wie folgt durchbricht: for (var k im Array) {} oder for (var k im Objekt) und diese Redewendung - obwohl sie möglicherweise fehlerhaft ist - ist sehr häufig. Zum Beispiel bricht es laut Matthew Darwins Antwort unten Google Maps.
Sam Watkins

42

Sie können verwenden Object.keys

Object.keys(h)

3
In ECMAScript 5 hinzugefügt, sollte aber jetzt in den meisten gängigen Browsern funktionieren
Pat

33

Sie können Underscore.js verwenden , eine Javascript-Dienstprogrammbibliothek.

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

Nun, es ist nicht wirklich das, was gefragt wurde, weil @Pat nach einer eingebauten Funktion sucht, aber es ist trotzdem eine interessante Bibliothek, die sich nicht ändertObject.prototype
fresskoma

2
Heutzutage denke ich, dass es viel hilfreicher ist, diese raffinierten kleinen Bibliotheks-Lets zu verwenden, als weiterhin eigene Implementierungen zu schreiben ... Wie auch immer, in den meisten realen Projekten verwenden wir sowieso Unterstriche oder gleichwertige Bibliotheken. Persönlich würde ich lieber mit Unterstrich gehen.
Kumarshar

_.keys(obj).lengthum zu sehen, ob es irgendwelche Schlüssel gibt.
Chovy

13

Soweit ich weiß, ist dies das Beste, was Sie tun können ...

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

2
Dies funktioniert auch nicht, wenn Object.prototype durcheinander gebracht wurde.
Phil

4
Es wäre besser, dies zu verwenden und nicht mit Object.prototype "herumzuspielen". Es scheint, dass alles kaputt geht, wenn wir Object.prototype Dinge hinzufügen: Es ist eine äußerst verbreitete Redewendung, die Schlüssel eines Arrays / Objekts zu durchlaufen.
Sam Watkins

8

Mit jQuery können Sie die Schlüssel wie folgt erhalten:

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

Oder:

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

danke an @pimlottc


3
Wenn Sie diese Route gehen JQuery.map$.map(h, function(v,k) { return k; });
möchten

6

Ich glaube, Sie können die Eigenschaften des Objekts mit for / in durchlaufen, um so etwas zu tun:

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

4

Ich wollte die oben am besten bewertete Antwort verwenden

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

In Verbindung mit der Google Maps API v3 ist Google Maps jedoch nicht funktionsfähig.

for (var key in h) ...

funktioniert gut.


1

Wenn Sie versuchen, nur die Elemente, aber nicht die Funktionen abzurufen, kann Ihnen dieser Code helfen

this.getKeys = function() {

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

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

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

}}

Dies ist Teil meiner Implementierung der HashMap und ich möchte nur die Schlüssel, thisist das Hashmap-Objekt, das die Schlüssel enthält

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.