Frage Wie kann ich ein JavaScript-Objekt durchlaufen oder aufzählen?


Ich habe ein JavaScript-Objekt wie das Folgende:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

Jetzt möchte ich alle durchschleifen p Elemente (p1,p2,p3...) und ihre Schlüssel und Werte bekommen. Wie kann ich das machen?

Ich kann das JavaScript-Objekt bei Bedarf ändern. Mein oberstes Ziel ist es, einige Schlüssel-Wert-Paare zu durchlaufen und wenn möglich, die Verwendung zu vermeiden eval.


2129
2018-03-26 06:01


Ursprung


Antworten:


Du kannst den ... benutzen for-in Schleife wie von anderen gezeigt. 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:

var p = {
    "p1": "value1",
    "p2": "value2",
    "p3": "value3"
};

for (var key in p) {
    if (p.hasOwnProperty(key)) {
        console.log(key + " -> " + p[key]);
    }
}


3460
2018-03-26 06:12



Unter ECMAScript 5 können Sie kombinieren Object.keys() und Array.prototype.forEach():

var obj = { first: "John", last: "Doe" };

Object.keys(obj).forEach(function(key) {
    console.log(key, obj[key]);
});

ES6 fügt hinzu for...of:

for (const key of Object.keys(obj)) {
    console.log(key, obj[key]);
}

ES2017 fügt hinzu Object.entries() wodurch vermieden wird, jeden Wert im ursprünglichen Objekt nachschlagen zu müssen:

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

Beide Object.keys() und Object.entries() Iterieren Sie Eigenschaften in der gleichen Reihenfolge wie a for...in Schleife aber ignoriere die Prototypkette. Nur die eigenen aufzählbaren Eigenschaften des Objekts werden iteriert.

Bearbeiten: ES2016 → ES6


621
2018-04-20 21:59



Du musst das benutzen Einlaufschleife

Aber sei vorsichtig, wenn du diese Art von Schleife verwendest, denn das wird Schleife alle Eigenschaften entlang der Prototypkette.

Verwenden Sie daher bei For-In-Loops immer das hasOwnProperty Methode, um festzustellen, ob die aktuelle Eigenschaft in Iteration wirklich eine Eigenschaft des Objekts ist, das Sie überprüfen:

for (var prop in p) {
    if (!p.hasOwnProperty(prop)) {
        //The current property is not a direct property of p
        continue;
    }
    //Do your logic with the property here
}

300
2018-03-26 06:12



Die Frage wird nicht vollständig sein, wenn wir keine alternativen Methoden zum Durchschleifen von Objekten erwähnen.

Heutzutage stellen viele bekannte JavaScript-Bibliotheken ihre eigenen Methoden zum Iterieren über Sammlungen, d. H Arrays, Objekte, und Array-ähnliche Objekte. Diese Methoden sind bequem zu verwenden und sind vollständig mit jedem Browser kompatibel.

  1. Wenn du mit arbeitest jQuery, können Sie verwenden jQuery.each() Methode. Es kann verwendet werden, um nahtlos über Objekte und Arrays zu iterieren:

    $.each(obj, function(key, value) {
        console.log(key, value);
    });
    
  2. Im Underscore.js Sie können Methode finden _.each(), die über eine Liste von Elementen iteriert, die wiederum jeweils eine angegebene Funktion ergeben (achten Sie auf die Reihenfolge der Argumente in iteratee Funktion!):

    _.each(obj, function(value, key) {
        console.log(key, value);
    });
    
  3. Lo-Strich bietet mehrere Methoden zum Iterieren von Objekteigenschaften. Basic _.forEach() (oder es ist Alias _.each()) eignet sich zum Durchschleifen von Objekten und Arrays, jedoch (!) Objekten mit length Eigenschaften werden wie Arrays behandelt. Um dieses Verhalten zu vermeiden, wird empfohlen, sie zu verwenden _.forIn() und _.forOwn() Methoden (diese haben auch value Argument kommt zuerst):

    _.forIn(obj, function(value, key) {
        console.log(key, value);
    });
    

    _.forIn() iteriert über eigen und geerbt aufzählbare Eigenschaften eines Objekts, während _.forOwn() iteriert nur über besitzen Eigenschaften eines Objekts (grundsätzlich gegen hasOwnProperty Funktion). Für einfache Objekte und Objektliterale funktionieren alle diese Methoden.

Im Allgemeinen haben alle beschriebenen Methoden das gleiche Verhalten bei allen gelieferten Objekten. Neben der Verwendung von nativ for..in Schleife wird normalerweise sein schneller als irgendeine Abstraktion, wie jQuery.each()Diese Methoden sind wesentlich einfacher zu verwenden, erfordern weniger Codierung und bieten eine bessere Fehlerbehandlung.


230
2018-01-20 17:58



In ECMAScript 5 haben Sie einen neuen Ansatz in Iterationsfeldern von Literalen - Object.keys

Weitere Informationen, die Sie sehen können MDN

Meine Wahl ist unten als eine schnellere Lösung in aktuellen Versionen von Browsern (Chrome30, IE10, FF25)

var keys = Object.keys(p),
    len = keys.length,
    i = 0,
    prop,
    value;
while (i < len) {
    prop = keys[i];
    value = p[prop];
    i += 1;
}

Sie können die Leistung dieses Ansatzes mit verschiedenen Implementierungen vergleichen jsperf.com:

Browser-Unterstützung, auf der Sie sehen können Kangax's Kompat-Tabelle

Für den alten Browser hast du einfach und voll Polyfill

UPD:

Leistungsvergleich für alle beliebtesten Fälle in dieser Frage auf perfjs.info:

Objekt literal Iteration


47
2017-11-16 19:59



Sie können einfach darüber iterieren wie:

for (var key in p) {
  alert(p[key]);
}

Beachten Sie, dass key wird den Wert der Eigenschaft nicht übernehmen, es ist nur ein Indexwert.


30
2018-03-26 06:05



Da es2015 immer populärer wird, poste ich diese Antwort, die Gebrauch des Generators und des Iterators einschließt, um glatt zu durchlaufen [key, value] Paare. Wie es in anderen Sprachen zum Beispiel Ruby möglich ist.

Ok, hier ist ein Code:

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
  [Symbol.iterator]: function* () {
    for (const i of Object.keys(this)) {
      yield [i, this[i]];
    }
  }
};

for (const [k, v] of MyObject) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Alle Informationen darüber, wie Sie einen Iterator und Generator erstellen können, finden Sie auf der Mozilla-Entwickler-Seite.

Hoffnung Es hat jemandem geholfen.

BEARBEITEN:

ES2017 wird enthalten Object.entries das wird über iterieren [key, value] Paare in Objekten noch einfacher. Es ist jetzt bekannt, dass es ein Teil eines Standards nach dem sein wird ts39 Bühneninformation.

Ich denke, es ist Zeit, meine Antwort zu aktualisieren, damit sie noch frischer wird als jetzt.

const MyObject = {
  'a': 'Hello',
  'b': 'it\'s',
  'c': 'me',
  'd': 'you',
  'e': 'looking',
  'f': 'for',
};

for (const [k, v] of Object.entries(MyObject)) {
  console.log(`Here is key ${k} and here is value ${v}`);
}

Sie können mehr über die Verwendung finden MDN Seite


24
2017-08-27 09:06



über Prototyp mit für jede() was sollte die überspringen Prototyp-Kette Eigenschaften:

Object.prototype.each = function(f) {
    var obj = this
    Object.keys(obj).forEach( function(key) { 
        f( key , obj[key] ) 
    });
}


//print all keys and values
var obj = {a:1,b:2,c:3}
obj.each(function(key,value) { console.log(key + " " + value) });
// a 1
// b 2
// c 3

17
2017-12-09 05:05



Nachdem ich hier alle Antworten durchgelesen habe, ist hasOwnProperty nicht für meine eigene Verwendung erforderlich, da mein Json-Objekt sauber ist; Es hat keinen Sinn, zusätzliche JavaScript-Verarbeitungen hinzuzufügen. Das ist alles was ich benutze:

for (var key in p) {
    console.log(key + ' => ' + p[key]);
    // key is key
    // value is p[key]
}

14
2017-08-18 20:50



for(key in p) {
  alert( p[key] );
}

Hinweis: Sie können dies über Arrays tun, aber Sie iterieren über die length und andere Eigenschaften auch.


14
2018-03-26 06:04



Es sind interessante Leute in diesen Antworten, die beide berührt haben Object.keys() und for...of aber nie kombiniert sie:

var map = {well:'hello', there:'!'};
for (let key of Object.keys(map))
    console.log(key + ':' + map[key]);

Du kannst nicht einfach for...of ein Object weil es kein Iterator ist und for...index oder .forEach()den Object.keys() ist hässlich / ineffizient.
Ich bin froh, dass die meisten Leute davon Abstand nehmen for...in (mit oder ohne Überprüfung .hasOwnProperty()) da das auch ein bisschen chaotisch ist, also anders als meine Antwort oben, ich bin hier um zu sagen ...


Sie können normale Objektverknüpfungen iterieren lassen! Benehmen sich genau wie Maps mit direktem Einsatz der Phantasie for...of
DEMO Arbeiten in Chrome und FF (ich nehme nur ES6 an)

var ordinaryObject = {well:'hello', there:'!'};
for (let pair of ordinaryObject)
    //key:value
    console.log(pair[0] + ':' + pair[1]);

//or
for (let [key, value] of ordinaryObject)
    console.log(key + ':' + value);

So lange du mein Shim unterlegst:

//makes all objects iterable just like Maps!!! YAY
//iterates over Object.keys() (which already ignores prototype chain for us)
Object.prototype[Symbol.iterator] = function() {
    var keys = Object.keys(this)[Symbol.iterator]();
    var obj = this;
    var output;
    return {next:function() {
        if (!(output = keys.next()).done)
            output.value = [output.value, obj[output.value]];
        return output;
    }};
};

Ohne ein echtes Map-Objekt erstellen zu müssen, das nicht den schönen syntaktischen Zucker enthält.

var trueMap = new Map([['well', 'hello'], ['there', '!']]);
for (let pair of trueMap)
    console.log(pair[0] + ':' + pair[1]);

In der Tat, wenn Sie mit dieser Unterlage die anderen Funktionen von Map ausnutzen wollten (ohne sie alle zu shimmen), aber trotzdem die ordentliche Objektnotation verwenden wollten, da Objekte jetzt iterierbar sind, können Sie jetzt einfach eine Map daraus machen!

//shown in demo
var realMap = new Map({well:'hello', there:'!'});

Für diejenigen, die es nicht mögen sich zu scheren oder sich mit ihnen zu messen prototype im Allgemeinen, fühlen Sie sich frei, um die Funktion auf Fenster stattdessen zu machen und nennt es so getObjIterator() dann;

//no prototype manipulation
function getObjIterator(obj) {
    //create a dummy object instead of adding functionality to all objects
    var iterator = new Object();

    //give it what the shim does but as its own local property
    iterator[Symbol.iterator] = function() {
        var keys = Object.keys(obj)[Symbol.iterator]();
        var output;

        return {next:function() {
            if (!(output = keys.next()).done)
                output.value = [output.value, obj[output.value]];
            return output;
        }};
    };

    return iterator;
}

Jetzt kann man es einfach als normale Funktion bezeichnen, nichts anderes ist betroffen

var realMap = new Map(getObjIterator({well:'hello', there:'!'}))

oder

for (let pair of getObjIterator(ordinaryObject))

Es gibt keinen Grund, warum das nicht funktionieren würde.

Willkommen in der Zukunft.


14
2018-06-28 09:42