Durch Objekteigenschaften iterieren

2040

var obj = {
    name: "Simon",
    age: "20",
    clothing: {
        style: "simple",
        hipster: false
    }
}

for(var propt in obj){
    console.log(propt + ': ' + obj[propt]);
}

Wie proptrepräsentiert die Variable die Eigenschaften des Objekts? Es ist keine eingebaute Methode oder Eigenschaft. Warum kommt es mit jeder Eigenschaft im Objekt?

Rafay
quelle
11
if (typeof(obj[propt]) === 'object') {/ * Mach es noch einmal * /}
noob
13
Tut mir wirklich leid für diese Frage. Ich weiß, was eine Schleife ist, ich konnte mich nicht darum kümmern, "Objekteigenschaften zu durchlaufen", was meiner Meinung nach jetzt gelöscht ist. Außerdem haben sie mir empfohlen "JavaScript Schritt für Schritt 2. Ausgabe - Steve Suehring in der Schule.
Rafay
242
Dies ist eine gute Frage für Anfänger. Ich möchte hinzufügen, dass ich 15 Jahre Berufserfahrung mit anderen Sprachen habe und diese Antwort brauchte. Ich würde plus 2000, wenn ich könnte.
Nathan C. Tresch
60
Verrückt, aber ich komme seit Jahren alle paar Monate auf diese Seite, um die Syntax dafür neu zu lernen. Ich erinnere mich nicht daran, wie das geht ... Ich erinnere mich nur daran, dass diese Seite immer hier auf SO ist.
HDave
14
Dies ist die seltsamste Seite, die ich auf StackOverflow gesehen habe. Wenn Sie die Frage sorgfältig lesen, versucht nur eine Antwort zu beantworten, was tatsächlich gestellt wird, und sie hat eine Punktzahl von -6. Die Antwort mit der höchsten Punktzahl, die akzeptiert wurde, antwortet nicht nur nicht, sondern ist einfach falsch.

Antworten:

2426

Das Iterieren über Eigenschaften erfordert diese zusätzliche hasOwnPropertyPrüfung:

for (var prop in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, prop)) {
        // do stuff
    }
}

Dies ist erforderlich, da der Prototyp eines Objekts zusätzliche Eigenschaften für das Objekt enthält, die technisch Teil des Objekts sind. Diese zusätzlichen Eigenschaften werden von der Basisobjektklasse geerbt, sind jedoch weiterhin Eigenschaften von obj.

hasOwnProperty Überprüft einfach, ob dies eine für diese Klasse spezifische Eigenschaft ist und keine von der Basisklasse geerbte.


Es ist auch möglich, hasOwnPropertydas Objekt selbst aufzurufen :

if (obj.hasOwnProperty(prop)) {
    // do stuff
}

Dies schlägt jedoch fehl, wenn das Objekt ein nicht verwandtes Feld mit demselben Namen hat:

var obj = { foo: 42, hasOwnProperty: 'lol' };
obj.hasOwnProperty('foo');  // TypeError: hasOwnProperty is not a function

Deshalb ist es sicherer, es Object.prototypestattdessen durchzurufen:

var obj = { foo: 42, hasOwnProperty: 'lol' };
Object.prototype.hasOwnProperty.call(obj, 'foo');  // true
Lambda-Fee
quelle
21
@BT Laut Mozilla-Dokumentation : "Wenn Sie nur Eigenschaften berücksichtigen möchten, die an das Objekt selbst angehängt sind, und nicht seine Prototypen, verwenden Sie getOwnPropertyNames oder führen Sie eine hasOwnProperty-Prüfung durch (propertyIsEnumerable kann ebenfalls verwendet werden)."
Davidmdem
3
Was genau ist der Sinn des Anrufs object.hasOwnProperty()? Bedeutet die Tatsache, dass propertywas auch immer Wert hat, nicht, dass es in ist object?
Alex S
6
Weil Alex S, der Prototyp eines Objekts, zusätzliche Eigenschaften für das Objekt enthält, die technisch Teil des Objekts sind. Sie werden von der Basisobjektklasse geerbt, sind jedoch weiterhin Eigenschaften. hasOwnProperty prüft einfach, ob dies eine für diese Klasse spezifische Eigenschaft ist und keine von der Basisklasse geerbte. Eine gute Erklärung: brianflove.com/2013/09/05/javascripts-hasownproperty-method
Kyle Richter
87
Ich sollte jedoch erwähnen, dass Object.keys (obj) jetzt eine viel bessere Lösung ist, um die Schlüssel des Objekts selbst zu erhalten. Link zur Mozilla-Dokumentation: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Kyle Richter
9
Eine wichtige Information fehlt. propertyist hier ein String, hätte aufgerufen werden sollen propertyName. Andernfalls kann es für JS-Neulinge wie mich zu Verwirrung kommen, dh was im Inneren zu tun ist if.
Neolisk
1136

Ab JavaScript 1.8.5 können Sie Object.keys(obj)ein Array von Eigenschaften abrufen, die für das Objekt selbst definiert sind (diejenigen, für die true zurückgegeben wird obj.hasOwnProperty(key)).

Object.keys(obj).forEach(function(key,index) {
    // key: the name of the object key
    // index: the ordinal position of the key within the object 
});

Dies ist besser (und besser lesbar) als die Verwendung einer For-In-Schleife.

Es wird in diesen Browsern unterstützt:

  • Firefox (Gecko): 4 (2,0)
  • Chrome: 5
  • Internet Explorer: 9

Siehe das Mozilla Developer Network Object.keys () ‚s Referenz für weitere Informationen.

Danny R.
quelle
7
Dies wird jetzt allgemeiner unterstützt: developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Dom Vinyard
3
Und wenn Sie die Unterstützung für alte Browser benötigen, können Sie diese verwenden polyfill
KyleMit
27
In Umgebungen, die dieses Sprachkonstrukt unterstützen, kann Array.foreach mit dieser Methode aufgerufen werden: Object.keys(myObject).forEach(function(key,index) { //key = the name of the object key //index = the ordinal position of the key within the object });
Todd Price
4
@ AJ_83 Es gibt keinen guten Weg, aus einem forEach () auszubrechen. Verwenden Sie in diesem Fall einige () und geben Sie true zurück, um zu brechen
Daniel Z.
11
Warum ist dies besser lesbar als For-In? for candidate in candidateStatus... scheint mir lesbar
Jona
309

Mädchen und Jungs, wir sind im Jahr 2019 und wir haben nicht so viel Zeit zum Tippen ... Also lasst uns dieses coole neue schicke ECMAScript 2016 machen:

Object.keys(obj).forEach(e => console.log(`key=${e}  value=${obj[e]}`));
Frank Roth
quelle
17
Wie unterscheidet sich das von Danny Rs Antwort?
Krillgar
27
Es ist ein Oneliner und verwendet eine Karte anstelle von forEach. Und auch die Konsole.log ist für manche Leute vielleicht interessant.
Frank Roth
Satly, das funktioniert nicht, wenn obj=window.performance.memory: - / Wo wie for in. dhvar obj = window.performance.memory; for( key in obj ) console.log( 'key=' + key + ' val=' + obj[key] );
Michaelangel007
2
window.performance.memorywird nur von Chrome unterstützt und Object.keys(obj)gibt ein leeres Array zurück. Das hat nichts damit zu tun .map.
Frank Roth
Für den Fall, dass jemand nicht edaran interessiert sein möchte, diesen Einzeiler neu zu strukturieren, um mehr als eine Sache gleichzeitig zu erledigen , habe ich diesen Kern veröffentlicht. Es ist im Grunde genau wie die meisten Hash-Implementierungen und verwendet ( (key) => (value) )stattdessen { key => value }, aber wenn Sie sich vorher nicht damit befassen mussten, könnte es Ihnen helfen, es besser zu visualisieren: gist.github.com/the-nose-knows/9f06e745a56ff20519707433e28a4fa8
kayleeFrye_onDeck
216

Es ist die for...in statement( MDN , ECMAScript-Spezifikation ).

Sie können es als lesen „ für jede Eigenschaft in dem objObjekt, jede Eigenschaft zum zuweisen PROPT Variable wiederum“.

Marc B.
quelle
1
Vielen Dank, ich verstehe es jetzt. Ich schlug mir den Kopf, ging Bücher und Google durch.
Rafay
21
Stimmen Sie mit @RightSaidFred überein, der inOperator und die forAnweisung sind überhaupt nicht beteiligt, die for-inAnweisung stellt eine Grammatikproduktion für sich dar : for ( LeftHandSideExpression in Expression ),for ( var VariableDeclarationNoIn in Expression )
CMS
2
Seltsamerweise hat diese Antwort so viele Stimmen, zumal diese populären Kommentare ihr zu widersprechen scheinen.
Doug Molineux
9
Warum ist dies als Antwort markiert? Es ist wahrscheinlich das am wenigsten hilfreiche in diesem Thread ..
computrius
3
Am wenigsten hilfreiche Antwort? Kommt darauf an, was das OP Ihrer Meinung nach gefragt hat. Als ich die Frage zum ersten Mal las, schien es mir eine verblüffte Verwirrung über den Mechanismus zu sein, mit dem eine Variable verwendet werden kann, um die Eigenschaften eines Objekts zu untersuchen, und den diese Antwort eloquent erklärt (ungeachtet der 'for-in'-Fehlbezeichnung). Die Frage "Warum kommt es mit jeder Eigenschaft", die ich sehe, könnte bedeuten, dass das OP nach hasOwnProperty gesucht hat, es aber nicht weiß, aber ich denke, es ist wahrscheinlicher, dass dies das war, was das OP wissen wollte und eine korrekte Annahme falsch akzeptiert hat Antwort auf eine andere Frage. :-)
Bumpy
157

In aktuellen Implementierungen von ES können Sie Folgendes verwenden Object.entries:

for (const [key, value] of Object.entries(obj)) { }

oder

Object.entries(obj).forEach(([key, value]) => ...)

Wenn Sie nur die Werte durchlaufen möchten, verwenden Sie Object.values:

for (const value of Object.values(obj)) { }

oder

Object.values(obj).forEach(value => ...)
OneHoopyFrood
quelle
Dies wäre die beste Lösung (object.entries ...), aber ich kann sie nicht verwenden. Wenn Sie dies mehrmals tun möchten und es in Ihrem Framework nicht unterstützen können, können Sie die Polyfüllung auf dieser Seite verwenden: developer.mozilla.org/nl/docs/Web/JavaScript/Reference/…
Mario
Der dritte Vorschlag ist großartig, wenn Sie nur die Werte der Eigenschaften verwenden. Genial!
Ginzburg
27

Wenn Ihre Umgebung ES2017 unterstützt, würde ich Object.entries empfehlen :

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`);
});

Wie in der Dokumentation zu Mozillas Object.entries () gezeigt :

Die Object.entries () -Methode gibt ein Array der enumerierbaren Eigenschaftspaare [Schlüssel, Wert] eines bestimmten Objekts in derselben Reihenfolge zurück, wie sie von einer for ... in-Schleife bereitgestellt wird (der Unterschied besteht darin, dass eine for-in-Schleife auflistet Eigenschaften auch in der Prototypenkette).

Grundsätzlich können wir mit Object.entries auf den folgenden zusätzlichen Schritt verzichten, der mit dem älteren for ... in loop erforderlich ist :

// This step is not necessary with Object.entries
if (object.hasOwnProperty(property)) {
  // do stuff
}
JSON C11
quelle
22

Mit jquery können Sie dies jetzt tun:

$.each( obj, function( key, value ) {
  alert( key + ": " + value );
});
Rob Sedgwick
quelle
1
$.each({foo:1, length:0, bar:2}, function(k,v){console.log(k,v)})$ .each ist nicht für Objekte geeignet . Wenn ein Objekt zufällig eine Längeneigenschaft hat und sein Wert Null ist, wird das gesamte Objekt so behandelt, als wäre es ein leeres Array.
Bob Stein
Details, warum ich denke, dass dies ein Fehler einladender Ansatz ist .
Bob Stein
21

Dominiks Antwort ist perfekt, ich mache es einfach lieber so, da es sauberer zu lesen ist:

for (var property in object) {
    if (!object.hasOwnProperty(property)) continue;

    // Do stuff...
}
Cyril N.
quelle
Sollte aber Objectmit Großbuchstaben o sein, nein?
Jonathan
18

Die obigen Antworten sind etwas ärgerlich, da sie nicht erklären, was Sie in der for-Schleife tun, nachdem Sie sichergestellt haben, dass es sich um ein Objekt handelt: SIE ZUGREIFEN NICHT DIREKT! Sie erhalten tatsächlich nur den SCHLÜSSEL, den Sie für das OBJ benötigen:

var obj = {
  a: "foo",
  b: "bar",
  c: "foobar"
};

// We need to iterate the string keys (not the objects)
for(var someKey in obj)
{
  // We check if this key exists in the obj
  if (obj.hasOwnProperty(someKey))
  {
    // someKey is only the KEY (string)! Use it to get the obj:
    var myActualPropFromObj = obj[someKey]; // Since dynamic, use [] since the key isn't literally named "someKey"

    // NOW you can treat it like an obj
    var shouldBeBar = myActualPropFromObj.b;
  }
}

Dies ist alles ECMA5 sicher. Funktioniert sogar in lahmen JS-Versionen wie Rhino;)

dylanh724
quelle
15

Hinzufügen der Verwendung Reflect.ownKeys(obj)und Iteration von ES2015 über die Eigenschaften über einen Iterator.

Zum Beispiel:

let obj = { a: 'Carrot', b: 'Potato', Car: { doors: 4 } };

kann durch iteriert werden

// logs each key
Reflect.ownKeys(obj).forEach(key => console.log(key));

Wenn Sie direkt über die Werte der Schlüssel eines Objekts iterieren möchten, können Sie einen definieren iterator, genau wie die Standarditeratoren von JavaScipts für Zeichenfolgen, Arrays, typisierte Arrays, Map und Set.

JS versucht, über die Standard-Iterator-Eigenschaft zu iterieren, die als definiert werden muss Symbol.iterator.

Wenn Sie in der Lage sein möchten, alle Objekte zu durchlaufen, können Sie es als Prototyp von Object hinzufügen:

Object.prototype[Symbol.iterator] = function*() { 
    for(p of Reflect.ownKeys(this)){ yield this[p]; }
}

Auf diese Weise können Sie die Werte eines Objekts mit einer for ... of-Schleife durchlaufen, z. B.:

for(val of obj) { console.log('Value is:' + val ) }

Achtung : Zum Zeitpunkt des Schreibens dieser Antwort (Juni 2018) unterstützen alle anderen Browser außer IE Generatoren und for...ofIterationen überSymbol.iterator

Dimitar Nikovski
quelle
Obwohl Sie die Frage des OP nicht wirklich beantworten, war dies für mich sehr hilfreich, ich wusste noch nichts über Reflect.
Michiel
15
if(Object.keys(obj).length) {
    Object.keys(obj).forEach(key => {
        console.log("\n" + key + ": " + obj[key]);
    });
}

// *** Explanation line by line ***

// Explaining the bellow line
// It checks if obj has at least one property. Here is how:
// Object.keys(obj) will return an array with all keys in obj
// If there is no keys in obj, it will return empty array = []
// Then it will get it's length, if it has at least one element,
// it's bigger than 0 which evaluates to true and the bellow 
// code will be executed.
// Else means it's length = 0 which evaluates to false
// NOTE: you can use Object.hasOwnProperty() instead of Object.keys(obj).length
if(Object.keys(obj).length) {

    // Explaining the bellow line
    // Just like in the previous line, this returns an array with
    // all keys in obj (because if code execution got here, it means 
    // obj has keys.) 
    // Then just invoke built-in javascript forEach() to loop
    // over each key in returned array and calls a call back function 
    // on each array element (key), using ES6 arrow function (=>)
    // Or you can just use a normal function ((key) { blah blah }).
    Object.keys(obj).forEach(key => {

        // The bellow line prints out all keys with their 
        // respective value in obj.
        // key comes from the returned array in Object.keys(obj)
        // obj[key] returns the value of key in obj
        console.log("\n" + key + ": " + obj[key]);
    });
}
Fouad Boukredine
quelle
3
Hallo, könnten Sie weitere Informationen zu Ihrer Antwort hinzufügen, da nur Code nicht hilft?
Nicolas
Hallo @Nicolas, ich habe dem Code eine zeilenweise Erklärung hinzugefügt. Lassen Sie mich wissen, wenn es immer noch nicht klar ist
Fouad Boukredine
Da forEach leere Werte übersprungen werden , könnten Sie das Wenn und Object.keys(obj).forEach(e => console.log(`key=${e} value=${obj[e]}`));die Antwort von Frank Roth einfach loswerden .
Darkproduct
12

Die for ... in-Schleife repräsentiert jede Eigenschaft in einem Objekt, da sie genau wie eine for-Schleife ist. Sie haben propt in der for ... in-Schleife definiert, indem Sie Folgendes getan haben:

    for(var propt in obj){
alert(propt + ': ' + obj[propt]);
}

Eine for ... in-Schleife durchläuft die aufzählbaren Eigenschaften eines Objekts. Die Variable, die Sie definieren oder in die for ... in-Schleife einfügen, ändert sich jedes Mal, wenn Sie zur nächsten iterierten Eigenschaft wechseln. Die Variable in der for ... in-Schleife durchläuft die Schlüssel, aber der Wert ist der Wert des Schlüssels. Zum Beispiel:

    for(var propt in obj) {
      console.log(propt);//logs name
      console.log(obj[propt]);//logs "Simon"
    }

Sie können sehen, wie sich die Variable vom Wert der Variablen unterscheidet. Im Gegensatz dazu macht eine for ... of-Schleife das Gegenteil.

Ich hoffe das hilft.

Vappor Washmade
quelle
11
let obj = {"a": 3, "b": 2, "6": "a"}

Object.keys(obj).map((item) => {console.log("item", obj[item])})

// a
// 3
// 2
Philll_t
quelle
1
Wie in anderen Kommentaren erwähnt, forEachist dies hier besser geeignet, da mapein neues Array mit den Ergebnissen des Aufrufs des Codeblocks bei jeder Iteration zurückgegeben werden soll. Wir interessieren uns jedoch nur für die Nebeneffekte jeder Iteration, nicht für den Rückgabewert. Daher benötigen wir nicht das neue Array, mapdas uns zur Verfügung steht.
Danny
11
Object.keys(obj).forEach(key =>
  console.log(`key=${key} value=${obj[key]}`)
);
Fremder
quelle
10

Sie können Lodash verwenden. Die Dokumentation

var obj = {a: 1, b: 2, c: 3};
_.keys(obj).forEach(function (key) {
    ...
});
viktarpunko
quelle
10
Warum um alles in der Welt hat diese "Antwort" 10 positive Stimmen? Die Frage wird überhaupt nicht beantwortet. Ich fange an, das Vertrauen in die Intelligenz eines durchschnittlichen JS-Entwicklers zu verlieren.
Developerbmw
1
@developerbmw Ich verstehe, dass die Verwendung von ES6-Funktionen richtiger ist, aber ich habe vor einem Jahr geantwortet. Bitte teilen Sie uns Ihre Gedanken mit, wenn Sie eine Minute Zeit haben.
Viktarpunko
1
Die Idee ist, sich mehr auf native Methoden zu konzentrieren, anstatt dem Benutzer vorzuschlagen, seiner Seite eine 10000-Zeilenbibliothek hinzuzufügen. Versteh mich nicht falsch, ich benutze gerne Lodash, aber es gibt eine Zeit und einen Ort dafür und das ist es nicht.
9

Ihre forSchleife durchläuft alle Eigenschaften des Objekts obj. proptwird in der ersten Zeile Ihrer for-Schleife definiert. Es ist eine Zeichenfolge, die den Namen einer Eigenschaft des objObjekts darstellt. In der ersten Iteration der Schleife proptwäre "Name".

arb
quelle
9

Objekte in JavaScript sind Sammlungen von Eigenschaften und können daher für jede Anweisung in einer Schleife ausgeführt werden.

Sie sollten sich objeine Schlüsselwertsammlung vorstellen.


quelle
! mit dem wichtigen Unterschied, dass diese 'Listen von Eigenschaften' Namen als Schlüssel haben können, während normale JS-Arrays nur Zahlen als Schlüssel haben können.
Qqwy
9

Heutzutage können Sie ein Standard-JS-Objekt in ein iterierbares Objekt konvertieren, indem Sie einfach eine Symbol.iterator-Methode hinzufügen. Dann können Sie eine for ofSchleife verwenden und direkt auf ihre Werte zugreifen oder sogar einen Spread-Operator für das Objekt verwenden. Cool. Mal sehen, wie wir es schaffen können:

var o = {a:1,b:2,c:3},
    a = [];
o[Symbol.iterator] = function*(){
                       var ok = Object.keys(this);
                            i = 0;
                       while (i < ok.length) yield this[ok[i++]];
                     };
for (var value of o) console.log(value);
// or you can even do like
a = [...o];
console.log(a);

Reduzieren
quelle
1
Interessante Möglichkeit, das zu tun. Danke für die function*Entdeckung!
Benj
5

Wenn Sie Node ausführen, würde ich empfehlen:

Object.keys(obj).forEach((key, index) => {
    console.log(key);
});
Justin
quelle
5

Während die am besten bewertete Antwort korrekt ist, gibt es hier einen alternativen Anwendungsfall, dh wenn Sie über ein Objekt iterieren und am Ende ein Array erstellen möchten. Verwenden Sie .mapanstelle vonforEach

const newObj = Object.keys(obj).map(el => {
    //ell will hold keys 
   // Getting the value of the keys should be as simple as obj[el]
})
iRohitBhatia
quelle
4

Hinzufügen des rekursiven Weges:

function iterate(obj) {
    // watch for objects we've already iterated so we won't end in endless cycle
    // for cases like var foo = {}; foo.bar = foo; iterate(foo);
    var walked = [];
    var stack = [{obj: obj, stack: ''}];
    while(stack.length > 0)
    {
        var item = stack.pop();
        var obj = item.obj;
        for (var property in obj) {
            if (obj.hasOwnProperty(property)) {
                if (typeof obj[property] == "object") {
                  // check if we haven't iterated through the reference yet
                  var alreadyFound = false;
                  for(var i = 0; i < walked.length; i++)
                  {
                    if (walked[i] === obj[property])
                    {
                      alreadyFound = true;
                      break;
                    }
                  }
                  // new object reference
                  if (!alreadyFound)
                  {
                    walked.push(obj[property]);
                    stack.push({obj: obj[property], stack: item.stack + '.' + property});
                  }
                }
                else
                {
                    console.log(item.stack + '.' + property + "=" + obj[property]);
                }
            }
        }
    }
}

Verwendungszweck:

iterate({ foo: "foo", bar: { foo: "foo"} }); 
Ondrej Svejdar
quelle
1
@faiz - siehe meine Kommentare, es ist ein Schutz gegen das Feststecken in einer Endlosschleife, wenn Sie wiederholt durch ein Objekt mit zyklischen Referenzen gehen
Ondrej Svejdar
3

Was for..in loop tut, ist, dass es eine neue Variable (var someVariable) erstellt und dann jede Eigenschaft des angegebenen Objekts einzeln in dieser neuen Variablen (someVariable) speichert. Wenn Sie also Block {} verwenden, können Sie iterieren. Betrachten Sie das folgende Beispiel.

var obj = {
     name:'raman',
     hobby:'coding',
     planet:'earth'
     };

for(var someVariable in obj) {
  //do nothing..
}

console.log(someVariable); // outputs planet
Raman Sohi
quelle
Dies zu bewerten, da es einfach ist. In meinem Anwendungsfall muss ich alle Attribute in einem Objekt auf zweifelhafte Werte überprüfen - NaNs, Nullen, undefiniert (es waren Punkte in einem Diagramm, und diese Werte verhinderten das Zeichnen des Diagramms). Um den Wert anstelle des Namens zu erhalten, würden Sie in der Schleife einfach tun obj[someVariable]. Vielleicht liegt der Grund dafür, dass es so stark herabgestuft wurde, darin, dass es nicht rekursiv ist. Dies wäre also keine adäquate Lösung, wenn Sie ein stark strukturiertes Objekt haben.
Katharine Osborne
@KatharineOsborne oder vielleicht, weil der folgende Satz etwas kryptisch ist: "Wenn Sie also Block {} verwenden, können Sie iterieren." Der Code sagt mehr als der Text.
bvdb
3

Hier iteriere ich jeden Knoten und erstelle aussagekräftige Knotennamen. Wenn Sie bemerken, machen instanceOf Array und instanceOf Object so ziemlich dasselbe (in meiner Anwendung gebe ich jedoch eine andere Logik an).

function iterate(obj,parent_node) {
    parent_node = parent_node || '';
    for (var property in obj) {
        if (obj.hasOwnProperty(property)) {
            var node = parent_node + "/" + property;
            if(obj[property] instanceof Array) {
                //console.log('array: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            } else if(obj[property] instanceof Object){
                //console.log('Object: ' + node + ":" + obj[property]);
                iterate(obj[property],node)
            }
            else {
                console.log(node + ":" + obj[property]);
            }
        }
    }
}

Anmerkung - Ich bin von Ondrej Svejdars Antwort inspiriert. Diese Lösung hat jedoch eine bessere Leistung und ist weniger mehrdeutig

Faiz Mohamed Haneef
quelle
3

Grundsätzlich möchten Sie jede Eigenschaft im Objekt durchlaufen.

JSFiddle

var Dictionary = {
  If: {
    you: {
      can: '',
      make: ''
    },
    sense: ''
  },
  of: {
    the: {
      sentence: {
        it: '',
        worked: ''
      }
    }
  }
};

function Iterate(obj) {
  for (prop in obj) {
    if (obj.hasOwnProperty(prop) && isNaN(prop)) {
      console.log(prop + ': ' + obj[prop]);
      Iterate(obj[prop]);
    }
  }
}
Iterate(Dictionary);
HovyTech
quelle
obj(prop)<- TypeError: obj ist keine Funktion
le_m
@le_m mein schlechtes. Ich muss das hasOwnPropertyAttribut versehentlich herausgenommen haben. Es sollte jetzt funktionieren.
HovyTech
2

Ich möchte die obigen Antworten ergänzen, da Sie möglicherweise andere Absichten als Javascript haben. Ein JSON-Objekt und ein Javascript-Objekt sind verschiedene Dinge, und Sie möchten möglicherweise die Eigenschaften eines JSON-Objekts mit den oben vorgeschlagenen Lösungen durchlaufen und sich dann überraschen lassen.

Angenommen, Sie haben ein JSON-Objekt wie:

var example = {
    "prop1": "value1",
    "prop2": [ "value2_0", value2_1"],
    "prop3": {
         "prop3_1": "value3_1"
    }
}

Der falsche Weg, um seine 'Eigenschaften' zu durchlaufen:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        recursivelyIterateProperties(jsonObject[prop]);
    }
}

Sie könnten sehen die Konsolenprotokollierung überrascht sein 0, 1usw. , wenn das Iterieren durch die Eigenschaften prop1und prop2und prop3_1. Diese Objekte sind Sequenzen, und die Indizes einer Sequenz sind Eigenschaften dieses Objekts in Javascript.

Eine bessere Möglichkeit, die Eigenschaften eines JSON-Objekts rekursiv zu durchlaufen, besteht darin, zunächst zu überprüfen, ob es sich bei diesem Objekt um eine Sequenz handelt oder nicht:

function recursivelyIterateProperties(jsonObject) {
    for (var prop in Object.keys(example)) {
        console.log(prop);
        if (!(typeof(jsonObject[prop]) === 'string')
            && !(jsonObject[prop] instanceof Array)) {
                recursivelyIterateProperties(jsonObject[prop]);

            }

     }
}
Jadiel de Armas
quelle
1

Zur weiteren Verfeinerung der akzeptierte Antwort es ist erwähnenswert, dass , wenn Sie das Objekt mit einem instanziiert var object = Object.create(null)dann object.hasOwnProperty(property)wird eine Typeerror auslösen. Um auf der sicheren Seite zu sein, müssen Sie es vom Prototyp wie folgt aufrufen:

for (var property in object) {
    if (Object.prototype.hasOwnProperty.call(object, property)) {
        // do stuff
    }
}
Konrad Kuss
quelle