Ich habe ein JavaScript-Objekt wie das folgende:
var p = {
"p1": "value1",
"p2": "value2",
"p3": "value3"
};
Jetzt möchte ich eine Schleife durch alle p
Elemente ( p1
, p2
, p3
...) und ihre Schlüssel und Werte erhalten. Wie kann ich das machen?
Ich kann das JavaScript-Objekt bei Bedarf ändern. Mein letztendliches Ziel ist es, einige Schlüsselwertpaare zu durchlaufen, und wenn möglich möchte ich die Verwendung vermeiden eval
.
javascript
loops
for-loop
each
Tanmoy
quelle
quelle
Antworten:
Sie können die
for-in
Schleife wie von anderen gezeigt verwenden. Sie müssen jedoch auch sicherstellen, dass der Schlüssel, den Sie erhalten, eine tatsächliche Eigenschaft eines Objekts ist und nicht vom Prototyp stammt.Hier ist der Ausschnitt:
For-of mit Object.keys () Alternative:
Beachten Sie, dass die Verwendung von
for-of
anstelle vonfor-in
, wenn sie nicht verwendet wird, für benannte Eigenschaften undefiniert zurückgibt undObject.keys()
sicherstellt, dass nur die eigenen Eigenschaften des Objekts ohne die gesamten Eigenschaften der Prototypkette verwendet werdenMit der neuen
Object.entries()
Methode:Hinweis: Diese Methode wird von Internet Explorer nicht nativ unterstützt. Sie können eine Polyfill für ältere Browser verwenden.
quelle
alert(key + " -> " + JSON.stringify(p[key]));
__proto__
oderprototype
. Diese Eigenschaft hat einen Verweis auf das übergeordnete Objekt. Ein Objekt erbt automatisch Eigenschaften von seinem übergeordneten Objekt. Dies ist der Grund für die VerwendunghasOwnProperty
, was bedeutet, dass wir an Objekten interessiert sind, die Eigentum besitzen, und nicht an den übergeordneten Objekten.Unter ECMAScript 5 können Sie kombinieren
Object.keys()
undArray.prototype.forEach()
:ECMAScript 6 fügt hinzu
for...of
:ECMAScript 8 fügt hinzu,
Object.entries()
wodurch vermieden wird, dass jeder Wert im Originalobjekt nachgeschlagen werden muss:Sie können kombinieren
for...of
, destrukturieren undObject.entries
:Beide
Object.keys()
undObject.entries()
iterieren Eigenschaften in derselben Reihenfolge wie einefor...in
Schleife , ignorieren jedoch die Prototypkette . Es werden nur die eigenen aufzählbaren Eigenschaften des Objekts iteriert.quelle
Object.forEach(obj, function (value, key) {...})
? :( Sicherlichobj.forEach(function...)
wäre es kürzer und komplementärerArray.prototype.forEach
, aber das würde dazu führen, dass Objekte ihre eigeneforEach
Eigenschaft definieren . Ich nehme anObject.keys
, dass sie vor dem Rückruf schützen, der die Schlüssel des Objekts ändert.Object.forEach = function (obj, callback) { Object.keys(obj).forEach(function (key) { callback(obj[key], key); }); }
Object.entries(obj).map/forEach(([key, value]) => console.log(key, value))
([Schlüssel, Wert] ist eine Array-Destrukturierung, um direkt auf beide Elemente zuzugreifen. Und Sie müssen die Parameter in zusätzliche Parens einschließen.)index
den Schlüssel in JSON? Oder sollte ich bei Bedarf einen separaten Zähler verwenden?for...of
ist ES6-Standard, nicht ES2016.Sie müssen die For-In-Schleife verwenden
Seien Sie jedoch sehr vorsichtig, wenn Sie diese Art von Schleife verwenden, da hierdurch alle Eigenschaften entlang der Prototypenkette wiederholt werden .
Verwenden Sie daher bei der Verwendung von For-In-Schleifen immer die
hasOwnProperty
Methode, um festzustellen, ob die aktuelle Eigenschaft in der Iteration wirklich eine Eigenschaft des Objekts ist, das Sie überprüfen:quelle
{ }
persönlich entfernen, weil einif
ohne sie es ein wenig unklar macht, was Teil des istif
und was nicht. Aber ich denke, das ist nur eine{ }
hauptsächlich zu behalten , um Verwirrung zu vermeiden, wenn man später etwas zumif
Geltungsbereich hinzufügen muss .Object.prototype.hasOwnProperty.call(p, prop)
Aber auch dies kann nicht vor Manipulationen an Object.prototype schützen ...Die Frage wird nicht vollständig sein, wenn wir keine alternativen Methoden zum Durchlaufen von Objekten erwähnen.
Heutzutage bieten viele bekannte JavaScript-Bibliotheken ihre eigenen Methoden zum Iterieren über Sammlungen, dh über Arrays , Objekte und Array-ähnliche Objekte . Diese Methoden sind bequem zu verwenden und mit jedem Browser vollständig kompatibel.
Wenn Sie mit jQuery arbeiten , können Sie die
jQuery.each()
Methode verwenden. Es kann verwendet werden, um sowohl Objekte als auch Arrays nahtlos zu durchlaufen:In Underscore.js finden Sie die Methode
_.each()
, die über eine Liste von Elementen iteriert und jeweils eine bereitgestellte Funktion ergibt (achten Sie auf die Reihenfolge der Argumente in der iteratee- Funktion!):Lo-Dash bietet verschiedene Methoden zum Durchlaufen von Objekteigenschaften. Basic
_.forEach()
(oder sein Alias_.each()
) ist nützlich, um sowohl Objekte als auch Arrays zu durchlaufen. (!) Objekte mitlength
Eigenschaften werden jedoch wie Arrays behandelt. Um dieses Verhalten zu vermeiden, wird die Verwendung empfohlen_.forIn()
_.forOwn()
Methoden und Methoden zu verwenden (für diese steht auch dasvalue
Argument an erster Stelle):_.forIn()
iteriert über eigene und geerbte aufzählbare Eigenschaften eines Objekts, während_.forOwn()
nur über eigene Eigenschaften eines Objekts iteriert wird (im Grunde genommen gegen diehasOwnProperty
Funktion prüfen ). Für einfache Objekte und Objektliterale funktioniert jede dieser Methoden einwandfrei.Im Allgemeinen verhalten sich alle beschriebenen Methoden mit allen bereitgestellten Objekten gleich. Außerdem ist die Verwendung einer nativen
for..in
Schleife normalerweise schneller als jede Abstraktion.jQuery.each()
Diese Methoden sind erheblich einfacher zu verwenden, erfordern weniger Codierung und bieten eine bessere Fehlerbehandlung.quelle
In ECMAScript 5 haben Sie einen neuen Ansatz in Iterationsfeldern von Literal -
Object.keys
Weitere Informationen finden Sie auf MDN
Meine Wahl ist unten als schnellere Lösung in aktuellen Versionen von Browsern (Chrome30, IE10, FF25)
Sie können die Leistung dieses Ansatzes mit verschiedenen Implementierungen auf jsperf.com vergleichen :
Browserunterstützung finden Sie in der kompatiblen Tabelle von Kangax
Für alte Browser haben Sie eine einfache und vollständige Polyfüllung
UPD:
Leistungsvergleich für alle gängigsten Fälle in dieser Frage zu
perfjs.info
:Objektliteraliteration
quelle
Vorwort:
Hier im Jahr 2018 haben Sie folgende Möglichkeiten, die Eigenschaften eines Objekts zu durchlaufen (einige Beispiele folgen der Liste):
for-in
[ MDN , spec ] - Eine Schleifenstruktur, die die Namen der aufzählbaren Eigenschaften eines Objekts durchläuft , einschließlich der geerbten, deren Namen Zeichenfolgen sindObject.keys
[ MDN , spec ] - Eine Funktion, die ein Array mit den Namen der eigenen , aufzählbaren Eigenschaften eines Objekts bereitstellt , deren Namen Zeichenfolgen sind.Object.values
[ MDN , spec ] - Eine Funktion, die ein Array der Werte der eigenen , aufzählbaren Eigenschaften eines Objekts bereitstellt .Object.entries
[ MDN , spec ] - Eine Funktion, die ein Array mit den Namen und Werten der eigenen , aufzählbaren Eigenschaften eines Objekts bereitstellt (jeder Eintrag im Array ist ein[name, value]
Array).Object.getOwnPropertyNames
[ MDN , spec ] - Eine Funktion, die ein Array der Namen der eigenen Eigenschaften eines Objekts (auch nicht aufzählbarer) bereitstellt , deren Namen Zeichenfolgen sind.Object.getOwnPropertySymbols
[ MDN , spec ] - Eine Funktion, die ein Array der Namen der eigenen Eigenschaften eines Objekts (auch nicht aufzählbarer) bereitstellt , deren Namen Symbole sind.Reflect.ownKeys
[ MDN , spec ] - Eine Funktion , um ein Array der Namen eines Objekts bereitstellt eigenen Eigenschaften (auch nicht-enumerable sind), ob diese Namen Strings oder Symbole sind.Object.getPrototypeOf
[ MDN , spec ] und VerwendungObject.getOwnPropertyNames
,Object.getOwnPropertySymbols
oderReflect.ownKeys
auf jedes Objekt in der Prototypkette (zB am Ende der Antwort).Mit alle außer
for-in
, würden Sie eine Art Looping - Konstrukt auf dem Array (verwendenfor
,for-of
,forEach
, etc.).Beispiele:
for-in
::Code-Snippet anzeigen
Object.keys
(mit einerfor-of
Schleife, aber Sie können jedes Schleifenkonstrukt verwenden) :Code-Snippet anzeigen
Object.values
::Code-Snippet anzeigen
Object.entries
::Code-Snippet anzeigen
Object.getOwnPropertyNames
::Code-Snippet anzeigen
Object.getOwnPropertySymbols
::Code-Snippet anzeigen
Reflect.ownKeys
::Code-Snippet anzeigen
Alle Eigenschaften , einschließlich geerbter nicht aufzählbarer Eigenschaften :
Code-Snippet anzeigen
quelle
Sie können es einfach wie folgt durchlaufen:
Beachten Sie, dass
key
der Wert der Eigenschaft nicht angenommen wird, sondern nur ein Indexwert.quelle
Da es2015 immer beliebter wird, veröffentliche ich diese Antwort, die die Verwendung von Generator und Iterator zum reibungslosen Durchlaufen von
[key, value]
Paaren umfasst. Wie es in anderen Sprachen zum Beispiel Ruby möglich ist.Ok hier ist ein Code:
Alle Informationen dazu, wie Sie einen Iterator und Generator ausführen können, finden Sie auf der Entwickler-Mozilla-Seite.
Hoffe es hat jemandem geholfen.
BEARBEITEN:
ES2017 wird enthalten,
Object.entries
was das Iterieren über[key, value]
Paare in Objekten noch einfacher macht. Es ist jetzt bekannt, dass es Teil eines Standards gemäß ts39 sein wird .Ich denke, es ist Zeit, meine Antwort zu aktualisieren, damit sie noch frischer wird als jetzt.
Weitere Informationen zur Verwendung finden Sie auf der MDN- Seite
quelle
Hinweis: Sie können dies über Arrays tun, aber Sie werden auch über die
length
und andere Eigenschaften iterieren .quelle
key
wird nur ein Indexwert angenommen, sodass nur 0, 1, 2 usw. angezeigt werden. Sie müssen auf p [key] zugreifen.var p = {"p1":"q","p2":"w"}; for(key in p) { alert( key ); }
knallt "p1" und "p2" in Warnungen, also was ist daran falsch ???Nachdem ich alle Antworten hier durchgesehen habe, ist hasOwnProperty für meine eigene Verwendung nicht erforderlich, da mein json-Objekt sauber ist. Es macht wirklich keinen Sinn, zusätzliche Javascript-Verarbeitung hinzuzufügen. Das ist alles was ich benutze:
quelle
Object.prototype
, wird diese von aufgelistetfor..in
. Wenn Sie sicher sind, dass Sie keine Bibliotheken verwenden, die dies tun, müssen Sie nicht aufrufenhasOwnProperty
.Object.create(null)
über einen Prototyp mit forEach (), der die Eigenschaften der Prototypenkette überspringen sollte :
quelle
obj = { print: 1, each: 2, word: 3 }
produziertTypeError: number is not a function
. Die VerwendungforEach
zur Anpassung an die ähnlicheArray
Funktion kann das Risiko etwas verringern.Es ist interessant, dass Menschen in diesen Antworten beide berührt
Object.keys()
undfor...of
sie nie kombiniert haben:Sie können nicht einfach
for...of
ein,Object
weil es kein Iterator ist,for...index
oder.forEach()
dasObject.keys()
ist hässlich / ineffizient.Ich bin froh, dass die meisten Leute davon Abstand nehmen
for...in
(mit oder ohne Überprüfung.hasOwnProperty()
), da dies auch etwas chaotisch ist. Abgesehen von meiner obigen Antwort bin ich hier, um zu sagen ...Sie können gewöhnliche Objektassoziationen iterieren lassen! Benimm dich wie
Map
s mit direkter Verwendung des ausgefallenenfor...of
DEMO , das in Chrome und FF funktioniert (ich nehme nur ES6 an)
Solange Sie meine Unterlegscheibe unten angeben:
Ohne ein echtes Map-Objekt erstellen zu müssen, das nicht den schönen syntaktischen Zucker enthält.
Wenn Sie mit diesem Shim die anderen Funktionen von Map nutzen möchten (ohne sie alle einzuschränken), aber dennoch die saubere Objektnotation verwenden möchten, da Objekte jetzt iterierbar sind, können Sie jetzt einfach eine Map daraus erstellen!
Für diejenigen, die nicht gerne shimen oder sich
prototype
im Allgemeinen damit anlegen, können Sie die Funktion stattdessen im Fenster ausführen und sie so etwas wiegetObjIterator()
damals nennen.Jetzt können Sie es einfach als normale Funktion aufrufen, nichts anderes ist betroffen
oder
Es gibt keinen Grund, warum das nicht funktionieren würde.
Willkommen in der Zukunft.
quelle
For those who don't like to shim, or mess with prototype in general, feel free to make the function on window instead, calling it something like getObjIterator() then;
ordinaryObject
um zu betonen, dass die Magie für diese Typen immer noch funktioniert). Haben Sie die Demos überprüft? Was funktioniert bei dir nicht, @ noɥʇʎԀʎzɐɹƆ? (PS Ihr SE-Profilbild ist Chef)Sie erhalten also dieselbe Liste von Schlüsseln, die Sie beabsichtigen, indem Sie jeden Objektschlüssel mit hasOwnProperty testen. Sie benötigen diesen zusätzlichen Testvorgang nicht als und
Object.keys( obj ).forEach(function( key ){})
soll schneller sein. Lassen Sie es uns beweisen:In meinem Firefox habe ich folgende Ergebnisse
PS. auf Chrome ist der Unterschied noch größer http://codepen.io/dsheiko/pen/JdrqXa
PS2: In ES6 (EcmaScript 2015) können Sie iterierbare Objekte besser iterieren:
quelle
of
Map
Hier ist eine andere Methode zum Durchlaufen eines Objekts.
quelle
for
Methode möglicherweise leistungsfähiger.quelle
Sie können auch Object.keys () verwenden und die Objektschlüssel wie unten durchlaufen, um den Wert zu erhalten:
quelle
Nur JavaScript-Code ohne Abhängigkeiten:
quelle
Die
Object.keys()
Methode gibt ein Array der eigenen aufzählbaren Eigenschaften eines bestimmten Objekts zurück. Lesen Sie hier mehr darüberquelle
Performance
Heute 2020.03.06 teste ich ausgewählte Lösungen unter Chrome v80.0, Safari v13.0.5 und Firefox 73.0.1 unter MacOs High Sierra v10.13.6
Schlussfolgerungen
for-in
(A, B) , sind für alle Browser für große und kleine Objekte schnell (oder am schnellsten)for-of
(H) -Lösung auf Chrom für kleine und große Objekte schnelli
(J, K) basieren, sind in allen Browsern für kleine Objekte recht schnell (für Firefox auch schnell für große Objekte, in anderen Browsern jedoch mittelschnell).Einzelheiten
Leistungstests wurden für durchgeführt
In den folgenden Ausschnitten werden verwendete Lösungen vorgestellt
Code-Snippet anzeigen
Und hier sind Ergebnisse für kleine Objekte auf Chrom
quelle
Sie können allen Objekten eine einfache forEach- Funktion hinzufügen , sodass Sie jedes Objekt automatisch durchlaufen können:
Für diejenigen, die die " for ... in " -Methode nicht mögen :
Jetzt können Sie einfach anrufen:
Wenn Sie keine Konflikte mit anderen forEach-Methoden erhalten möchten, können Sie diese mit Ihrem eindeutigen Namen benennen.
quelle
Object
) wird im Allgemeinen als Anti-Pattern angesehen, da dies leicht zu Konflikten mit anderem Code führen kann. Wunde also nicht empfehlen, es so zu machen.Schleifen können bei Verwendung von reinem JavaScript sehr interessant sein. Es scheint, dass nur ECMA6 (New 2015 JavaScript Specification) die Schleifen unter Kontrolle gebracht hat. Während ich dies schreibe, haben leider sowohl Browser als auch die beliebte integrierte Entwicklungsumgebung (IDE) immer noch Probleme, die neuen Schnickschnack vollständig zu unterstützen.
Auf einen Blick sehen Sie hier, wie eine JavaScript-Objektschleife vor ECMA6 aussieht:
Ich weiß auch, dass dies bei dieser Frage nicht möglich ist, aber 2011 hat ECMAScript 5.1 die
forEach
Methode nur für Arrays hinzugefügt, die im Grunde eine neue verbesserte Methode zum Durchlaufen von Arrays geschaffen hat, während nicht iterierbare Objekte mit der alten ausführlichen und verwirrendenfor
Schleife belassen werden . Aber der seltsame Teil ist, dass diese neueforEach
Methode nicht unterstütztbreak
, was zu allen möglichen anderen Problemen führte.Grundsätzlich gibt es 2011 keinen wirklich soliden Weg, um JavaScript zu wiederholen, außer dem, was viele beliebte Bibliotheken (jQuery, Underscore usw.) für eine Neuimplementierung beschlossen haben.
Ab 2015 haben wir jetzt eine bessere Möglichkeit, jeden Objekttyp (einschließlich Arrays und Strings) zu schleifen (und zu brechen). So sieht eine Schleife in JavaScript schließlich aus, wenn die Empfehlung zum Mainstream wird:
Beachten Sie, dass die meisten Browser den obigen Code ab dem 18. Juni 2016 nicht mehr unterstützen. Selbst in Chrome müssen Sie dieses spezielle Flag aktivieren, damit es funktioniert:
chrome://flags/#enable-javascript-harmony
Bis dies zum neuen Standard wird, kann die alte Methode weiterhin verwendet werden, aber es gibt auch Alternativen in gängigen Bibliotheken oder sogar leichtgewichtige Alternativen für diejenigen, die keine dieser Bibliotheken verwenden.
quelle
Uncaught TypeError: Object.entries is not a function
. Ist es noch nicht in Chrome implementiert?In ES6 haben wir bekannte Symbole, um einige zuvor interne Methoden verfügbar zu machen. Sie können damit definieren, wie Iteratoren für dieses Objekt funktionieren:
Dies ergibt das gleiche Ergebnis wie die Verwendung von for ... in der es6-Schleife.
Es ist jedoch wichtig zu wissen, über welche Funktionen Sie jetzt mit es6 verfügen!
quelle
Object.keys()
Speicher generiert und im Speicher zugewiesen wird ... Cool!Ich würde dies tun, anstatt
obj.hasOwnerProperty
in jederfor ... in
Schleife zu überprüfen .quelle
quelle
json = [{"key1":"value1","key2":"value2"},{"key1":"value3","key2":"value4"}] for (var i = 0; i < json.length; i++) { for (var key in json[i]) { if (json[i].hasOwnProperty(key)) { console.log(key + " -> " + json[i][key]); } } }
Mit Hilfe eines
for-of
aufObject.keys()
Mögen:
quelle
Wenn Sie auch über nicht aufzählbare Eigenschaften iterieren möchten , können Sie
Object.getOwnPropertyNames(obj)
ein Array aller Eigenschaften (aufzählbar oder nicht aufzählbar) zurückgeben, die direkt auf einem bestimmten Objekt gefunden wurden.quelle
Error
Objekt überprüfen und konnte die Eigenschaften in einer Schleife oder einem_.forIn(err)
Aufruf nicht erreichen. MitObject.getOwnPropertyNames(err)
konnte ich auf alle Teile zugreifenError
, die ich vorher nicht erreichen konnte. Vielen Dank!Wenn jemand arrayObjects mit der Bedingung durchlaufen muss :
quelle
In Anbetracht von ES6 möchte ich meinen eigenen Löffel Zucker hinzufügen und einen weiteren Ansatz zum Durchlaufen der Objekteigenschaften bereitstellen.
Da ein einfaches JS-Objekt nicht sofort iterierbar ist , können wir die
for..of
Schleife nicht zum Durchlaufen des Inhalts verwenden. Aber niemand kann uns aufhalten , es iterierbar zu machen .Lassen Sie uns
book
Objekt haben.Da wir es geschafft haben, können wir es folgendermaßen verwenden:
Oder wenn Sie die Leistung von ES6- Generatoren kennen , können Sie den obigen Code sicherlich viel kürzer machen.
Sicher, Sie können ein solches Verhalten auf alle Objekte anwenden, indem Sie es
Object
aufprototype
Ebene iterierbar machen .Außerdem können Objekte, die dem iterierbaren Protokoll entsprechen, mit dem neuen ES2015-Feature- Spread- Operator verwendet werden, sodass Objekteigenschaftswerte als Array gelesen werden können.
Oder Sie können die Destrukturierungszuweisung verwenden :
Sie können JSFiddle mit dem gesamten Code auschecken , den ich oben angegeben habe.
quelle
seit ES06 können Sie die Werte eines Objekts als Array mit abrufen
Es gibt ein Array der Objektwerte zurück und extrahiert keine Werte aus Prototype !!
MDN DOCS Object.values ()
und für Schlüssel (hier schon vor mir beantwortet)
quelle
Im neuesten ES-Skript können Sie Folgendes tun:
quelle