976 Stimmen

Wie listet man die Eigenschaften eines JavaScript-Objekts auf?

Angenommen, ich erstelle ein Objekt wie folgt:

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

Was ist der beste Weg, um eine Liste der Eigenschaftsnamen abzurufen? d.h. ich möchte am Ende mit einigen variablen "Schlüssel", so dass:

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

3 Stimmen

Ein bisschen Off-Topic, aber wenn Sie underscore.js verwenden: _.keys(myJSONObject)

5 Stimmen

TL;DR: Wenn Sie nur aufzählbare Eigenschaften wünschen: Object.keys(obj) Manchmal möchte man auch nicht aufzählbare Eigenschaften haben. Denken Sie daran, wenn Sie dies tun! Um sie zu erhalten, verwenden Sie Object.getOwnPropertyNames(obj) stackoverflow.com/a/32413145/1599699

1225voto

slashnick Punkte 25307

In modernen Browsern (IE9+, FF4+, Chrome5+, Opera12+, Safari5+) können Sie die eingebaute Objekt.Schlüssel Methode:

var keys = Object.keys(myObject);

Die oben genannten hat eine vollständige Polyfill aber eine vereinfachte Version ist:

var getKeys = function(obj){
   var keys = [];
   for(var key in obj){
      keys.push(key);
   }
   return keys;
}

Alternativ ersetzen var getKeys con Object.prototype.keys um Ihnen den Aufruf von .keys() auf ein beliebiges Objekt. Das Erweitern des Prototyps hat einige Nebenwirkungen und ich würde nicht empfehlen, dies zu tun.

19 Stimmen

Ich würde noch einmal aktualisieren: "Sie könnten versucht sein, dies mit dem Prototyp zu tun ... aber tun Sie es nicht!

5 Stimmen

Möchte jemand die Frage klären, warum es nicht empfehlenswert ist, Funktionen zum Prototyp von Object hinzuzufügen?

2 Stimmen

Das ist eine ganz andere Frage, eine schnelle Suche hier auf Stackoverflow oder auf Google wird Ihnen viel zu lesen geben

273voto

Pablo Cabrera Punkte 5644

Als slashnick darauf hingewiesen, können Sie das "for in"-Konstrukt verwenden, um ein Objekt nach seinen Attributnamen zu durchsuchen. Sie werden jedoch über alle Attributnamen in der Prototypkette des Objekts iterieren. Wenn Sie iterieren wollen sólo über die eigenen Attribute des Objekts, können Sie mit der Object#hasOwnProperty() Methode. So haben die folgenden.

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

30 Stimmen

Ich wünschte, ich hätte dies vor der obigen Antwort von slashnic gelesen. Ich musste gerade 15 Minuten lang die Taste esc Schlüssel, weil das Objekt etwa eine Million Eigenschaften hatte, von denen die meisten nicht verwendet wurden, und ich eine Warnung dazu hatte.

1 Stimmen

Hier ist ein hervorragender Artikel von Zakas selbst zu diesem Thema: nczonline.net/blog/2010/07/27/

4 Stimmen

LOL @MarkHenderson - aber das nächste Mal sollten Sie den Prozess des Browsers einfach beenden und neu starten, anstatt 15 Minuten zu verschwenden :)

105voto

Andy E Punkte 324972

Wie Sam Dutton antwortete, wurde in ECMAScript 5th Edition eine neue Methode für diesen Zweck eingeführt. Object.keys() wird das tun, was Sie wollen, und wird unterstützt in Firefox 4 , Chrome 6, Safari 5 und IE 9 .

Sie können die Methode auch sehr einfach in Browsern implementieren, die sie nicht unterstützen. Einige der Implementierungen sind jedoch nicht vollständig mit dem Internet Explorer kompatibel. Hier ist eine besser kompatible Lösung:

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

Beachten Sie, dass die derzeit akzeptierte Antwort keine Prüfung auf hasOwnProperty() und gibt Eigenschaften zurück, die über die Prototypenkette vererbt werden. Es berücksichtigt auch nicht den berühmten DontEnum-Fehler im Internet Explorer, bei dem nicht aufzählbare Eigenschaften in der Prototypenkette dazu führen, dass lokal deklarierte Eigenschaften mit demselben Namen ihr DontEnum-Attribut erben.

Umsetzung von Object.keys() erhalten Sie eine robustere Lösung.

EDIT: im Anschluss an ein kürzlich geführtes Gespräch mit kangax einem bekannten Mitwirkenden an Prototype, habe ich die Abhilfe für den DontEnum-Fehler auf der Grundlage des Codes für seine Object.forIn() Funktion gefunden aquí .

0 Stimmen

Großartige Antwort, ich denke, die akzeptierte Antwort bleibt die leistungsfähigste genaue Lösung, vorausgesetzt, dass es immer ein JSON-Dict ist. Dies ist sicherlich derjenige, der anderswo zu verwenden.

1 Stimmen

@David Caunt: Danke :-) Leider würde die akzeptierte Antwort immer noch gegen den DontEnum-Bug verstoßen, und man weiß nie, welches JSON-Objekt einen String wie "valueOf" oder "constructor" als einen seiner Schlüssel haben könnte. Es wird auch über Erweiterungen iterieren Object.prototype . Es ist jedoch oft der Fall, dass kürzerer Code wesentlich ansprechender aussieht als größerer, robusterer Code, aber der Sinn dieser Antwort ist es, die ECMAScript 5th's Object.keys() die in Browsern, die dies nicht unterstützen, mit diesem Code implementiert werden kann. Die native Version wäre sogar noch leistungsfähiger als diese.

0 Stimmen

Guter Punkt - Sie haben Recht mit dem Fehler. Ich hoffe, jeder gute Entwickler würde für die nativen Methoden vor der Verwendung ihrer eigenen Implementierungen testen.

43voto

Sam Dutton Punkte 13932

Beachten Sie, dass Object.keys und andere ECMAScript 5-Methoden von Firefox 4, Chrome 6, Safari 5, IE 9 und höher unterstützt werden.

Zum Beispiel:

var o = {"foo": 1, "bar": 2}; 
alert(Object.keys(o));

ECMAScript 5-Kompatibilitätstabelle: http://kangax.github.com/es5-compat-table/

Beschreibung der neuen Methoden: http://markcaudill.com/index.php/2009/04/javascript-new-features-ecma5/

0 Stimmen

Probieren Sie auch keys() in der Konsole von Chrome Dev Tools, Firebug usw. aus.

0 Stimmen

37voto

Object.getOwnPropertyNames(obj)

Diese Funktion zeigt auch nicht aufzählbare Eigenschaften an, zusätzlich zu denen, die von Object.keys(obj) .

In JS hat jede Eigenschaft ein paar Eigenschaften, darunter eine boolesche enumerable .

Im Allgemeinen sind nicht aufzählbare Eigenschaften eher "intern" und werden seltener verwendet, aber es ist aufschlussreich, sie manchmal zu untersuchen, um zu sehen, was wirklich vor sich geht.

Beispiel:

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

Beachten Sie auch, wie:

  • Object.getOwnPropertyNames y Object.keys nicht in der Prototypenkette nach oben gehen und base
  • for in tut

Mehr über die Prototypenkette erfahren Sie hier: https://stackoverflow.com/a/23877420/895245

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X