it-swarm.com.de

Wie liste ich die Eigenschaften eines JavaScript-Objekts auf?

Angenommen, ich erstelle ein Objekt so:

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

Was ist der beste Weg, um eine Liste der Eigenschaftsnamen abzurufen? Ich möchte am Ende einige variable "Schlüssel" erhalten, die folgendermaßen aussehen:

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

In modernen Browsern (IE9 +, FF4 +, Chrome5 +, Opera12 +, Safari5 +) können Sie die integrierte Object.keys -Methode verwenden:

var keys = Object.keys(myObject);

Das oben genannte hat eine vollständige Füllmasse, aber eine vereinfachte Version ist:

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

Alternativ können Sie var getKeys durch Object.prototype.keys ersetzen, damit Sie .keys() für ein beliebiges Objekt aufrufen können. Die Erweiterung des Prototyps hat einige Nebenwirkungen und ich würde es nicht empfehlen.

962
slashnick

Wie auf slashnick hingewiesen wurde, können Sie das "for in" -Konstrukt verwenden, um ein Objekt nach seinen Attributnamen zu durchlaufen. Sie werden jedoch alle Attributnamen in der Prototypkette des Objekts durchlaufen. Wenn Sie only über die eigenen Attribute des Objekts iterieren möchten, können Sie die Object # hasOwnProperty () - Methode verwenden. Also das Folgende haben.

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

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 möchten, und wird in Firefox 4 , Chrome 6, Safari 5 und IE 9 unterstützt. 

Sie können die Methode auch sehr leicht in Browsern implementieren, die sie nicht unterstützen. Einige der Implementierungen sind jedoch nicht vollständig mit Internet Explorer kompatibel. Hier ist eine kompatibelere 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 aktuell akzeptierte Antwort keine Prüfung auf hasOwnProperty () enthält und Eigenschaften zurückgibt, die über die Prototypkette vererbt werden. Es berücksichtigt auch nicht den berühmten DontEnum-Fehler in Internet Explorer, bei dem nicht auflistbare Eigenschaften in der Prototypkette dazu führen, dass lokal deklarierte Eigenschaften mit demselben Namen ihr DontEnum-Attribut erben.

Durch die Implementierung von Object.keys () erhalten Sie eine robustere Lösung.

EDIT: Nach einer kürzlichen Diskussion mit kangax , einem bekannten Mitarbeiter von Prototype, habe ich die Problemumgehung für den DontEnum-Fehler basierend auf Code für seine Object.forIn()-Funktion gefunden. Hier .

97
Andy E

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

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

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

28
Sam Dutton

Object.getOwnPropertyNames(obj)

Diese Funktion zeigt zusätzlich zu den von Object.keys(obj) angezeigten Eigenschaften auch nicht aufzuzählende Eigenschaften.

In JS verfügt jede Eigenschaft über einige Eigenschaften, einschließlich einer booleschen Variable enumerable.

Im Allgemeinen sind nicht aufzuzählende Eigenschaften eher "innerlich" und werden weniger häufig verwendet, aber es ist aufschlussreich, manchmal nachzusehen, 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 und Object.keysnicht gehen in der Prototypkette nach base
  • for in tut

Mehr zur Prototypenkette hier: https://stackoverflow.com/a/23877420/895245

16
Matt

Könnte es mit jQuery wie folgt machen:

var objectKeys = $.map(object, function(value, key) {
  return key;
});
14
sbonami

wenn Sie versuchen, nur die Elemente abzurufen, nicht jedoch die Funktionen, 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. "Dies" ist das Hashmap-Objekt, das die Schlüssel enthält

9
zeacuss

Dies funktioniert in den meisten Browsern, auch in IE8, und es werden keine Bibliotheken jeglicher Art benötigt. var i ist dein schlüssel.

var myJSONObject =  {"ircEvent": "PRIVMSG", "method": "newURI", "regex": "^http://.*"}; 
var keys=[];
for (var i in myJSONObject ) { keys.Push(i); }
alert(keys);
8
qwerty_jones

Unter Browsern, die js 1.8 unterstützen:

[i for(i in obj)]
7
Rix Beck

Mozilla hat vollständige Implementierungsdetails wie es in einem Browser geht, wo es nicht unterstützt wird, wenn dies hilft:

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

Sie können es beliebig einfügen, möglicherweise aber in einer Art extensions.js-Datei oben in Ihrem Skriptstapel.

6

Da ich in fast jedem Projekt underscore.js verwende, würde ich die Funktion keys verwenden:

var obj = {name: 'gach', hello: 'world'};
console.log(_.keys(obj));

Die Ausgabe davon wird sein:

['name', 'hello']
4
schmijos

IE unterstützt (i in obj) nicht für native Eigenschaften. Hier ist eine Liste aller Requisiten, die ich finden konnte.

Es scheint, als würde Stackoverflow einige dumme Filterungen durchführen.

Die Liste ist am Ende dieses Google-Gruppenpostens verfügbar: - https://groups.google.com/group/hackvertor/browse_thread/thread/a9ba81ca642a63e0

4
Gareth Heyes

Aufbauend auf der akzeptierten Antwort. 

Wenn das Objekt Eigenschaften hat, die Sie aufrufen möchten, sagen Sie .properties () try!

var keys = Object.keys(myJSONObject);

for (var j=0; j < keys.length; j++) {
  Object[keys[j]].properties();
}
3
Sydwell

Die Lösung funktioniert an meinen Fällen und Browserübergreifend:

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

Verwenden Sie Reflect.ownKeys()

var obj = {a: 1, b: 2, c: 3};
Reflect.ownKeys(obj) // ["a", "b", "c"]

Object.keys und Object.getOwnPropertyNames können nicht nicht enumerable properties abrufen. Es funktioniert sogar für nicht-aufzählbare Eigenschaften.

var obj = {a: 1, b: 2, c: 3};
obj[Symbol()] = 4;
Reflect.ownKeys(obj) // ["a", "b", "c", Symbol()]
0
selmansamet