js - Wie listet man die Eigenschaften eines JavaScript-Objekts auf?



current of (14)

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

Sie können die Methode auch sehr einfach in Browsern implementieren, die dies nicht unterstützen. Einige der Implementierungen sind jedoch nicht vollständig kompatibel mit Internet Explorer. Ich habe dies in meinem Blog ausführlich beschrieben und eine kompatiblere Lösung erstellt:

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 () enthält und Eigenschaften zurückgibt , die über die Prototypkette geerbt werden. Es berücksichtigt auch nicht den berühmten DontEnum-Fehler in Internet Explorer, bei dem nicht aufzählbare 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.

Bearbeiten: Nach einer aktuellen Diskussion mit Kangax , ein bekannter Beitrag zu Prototype, implementierte ich die Problemumgehung für den DontEnum-Fehler basierend auf Code für seine Object.forIn() -Funktion here gefunden.

Sprich ich erstelle ein Objekt so:

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

Was ist der beste Weg, um eine Liste der Eigenschaftsnamen abzurufen? dh ich möchte mit einigen variablen "Schlüsseln" enden, so dass:

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


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

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

Die Ausgabe davon wird sein:

['name', 'hello']

Wenn Sie versuchen, nur die Elemente zu erhalten, aber nicht die Funktionen, dann 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, "das" ist das Hashmapping-Objekt, das die Schlüssel enthält


Wie slashnick darauf hingewiesen hat, können Sie das "for in" slashnick verwenden, um über ein Objekt für seine Attributnamen zu iterieren. Sie werden jedoch über alle Attributnamen in der Prototypkette des Objekts iterieren. Wenn Sie nur über die eigenen Attribute des Objekts iterieren möchten, können Sie die Methode Object#hasOwnProperty() verwenden. Also folgendes haben.

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

Könnte es mit jQuery wie folgt machen:

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

Sie können eine wiederverwendbare Komponente für Objektwerte verwenden, um alle Objektwerte abzurufen.

Beispiel:

values({ a: 1, b: 2, c: 3 }) // => [1, 2, 3]

Wie es funktioniert:

function values(object: {[any]: any}): any[] {
  const objValues = [];
  forEach(object, val => objValues.push(val)); 
  return objValues;
};

Dies funktioniert in den meisten Browsern, sogar in IE8, und es sind keine Bibliotheken erforderlich. Var ich ist dein Schlüssel.

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

Die Lösung funktioniert an meinen Fällen und Cross-Browser:

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

Mozilla hat vollständige Implementierungsdetails, wie man es in einem Browser macht, wo es nicht unterstützt wird, wenn das 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, aber möglicherweise in einer Datei extensions.js am Anfang des Skriptstapels.


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

var keys = Object.keys(myObject);

Das obige 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 Sie var getKeys durch Object.prototype.keys , damit Sie für jedes Objekt .keys() aufrufen .keys() . Die Erweiterung des Prototyps hat einige Nebenwirkungen und ich würde es nicht empfehlen.


Aufbauend auf der angenommenen Antwort.

Wenn das Objekt Eigenschaften hat, die Sie aufrufen wollen, sagen Sie .properties () versuchen Sie es!

var keys = Object.keys(myJSONObject);

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


Nur weil ich AngularJS erwähnt habe und gedacht habe, dass die Leute vielleicht wissen wollen ...

angular.copy bietet auch eine Methode zum tiefen Kopieren von Objekten und Arrays.





javascript