web-dev-qa-db-de.com

Verwenden von Objekten in For-of-Loops

Warum können Objekte nicht für for-Schleifen verwendet werden? Oder ist das ein Browserfehler? Dieser Code funktioniert in Chrome 42 nicht, da undefined keine Funktion ist:

test = { first: "one"}

for(var item of test) {
  console.log(item)
}
68
Daniel Herr

Ich habe Objekte mit diesem Code iterierbar gemacht:

Object.prototype[Symbol.iterator] = function*() {
 for(let key of Object.keys(this)) {
  yield([ key, this[key] ])
} }

Verwendungszweck:

for(let [ key, value ] of {}) { }

Alternativ:

for(let [ key, value ] of Object.entries({})) { }
18
Daniel Herr

Die for..of-Schleife unterstützt nur iterierbare Objekte wie Arrays, keine Objekte.

Um die Werte eines Objekts zu durchlaufen, verwenden Sie:

for (var key in test) {
    var item = test[key];
}
60
Overv

Wenn Sie Daten in einem Schlüsselwertspeicher speichern, verwenden Sie bitte Map , das explizit für diesen Zweck vorgesehen ist.

Wenn Sie jedoch ein Objekt verwenden müssen, können Sie in ES2017 (ES8) Object.values verwenden:

const foo = { a: 'foo', z: 'bar', m: 'baz' };
for (let value of Object.values(foo)) {
    console.log(value);
}

Wenn dies noch nicht unterstützt wird, verwenden Sie eine Polyfill: Alternative Version für Object.values()

Und wenn Sie eine ältere Umgebung unterstützen, die diese Syntax nicht unterstützt, müssen Sie forEach und Object.keys verwenden:

var obj = { a: 'foo', z: 'bar', m: 'baz' };
Object.keys(obj).forEach(function (prop) {
    var value = obj[prop];
    console.log(value);
});
31
Qantas 94 Heavy

Sie können diese Syntax verwenden:

let myObject = {first: "one"};

for(let [key, value] of Object.entries(myObject)) {
    console.log(key, value); // "first", "one"
}

Object.entries hat momentan schlechte Unterstützung funktioniert nicht in IE oder iOS Safari. Sie benötigen wahrscheinlich eine Polyfill.

28
mpen

Iterator, Iterable und for..of-Schleife in ECMAScript 2015/ES6

let tempArray = [1,2,3,4,5];

for(element of tempArray) {
  console.log(element);
}

// 1
// 2
// 3
// 4
// 5

Aber wenn wir das tun

let tempObj = {a:1, b:2, c:3};

for(element of tempObj) {
   console.log(element);
}
// error

Wir bekommen eine Fehlermeldung, weil die for..of -Schleife nur für Iterables funktioniert, dh für das Objekt, das einen @@ Iterator hat, der sich an - hält. Iterator-Protokoll, dh es muss ein Objekt mit der Methode next vorhanden sein. Die nächste Methode benötigt keine Argumente und sollte ein Objekt mit diesen beiden Eigenschaften zurückgeben.

erledigt: signalisiert, dass die Sequenz mit wahr beendet wurde, und falsch bedeutet, dass möglicherweise mehr Werte vorhanden sind Wert: Dies ist das aktuelle Element in der Sequenz

Also, um ein Objekt zu machen Iterable das heißt, damit es funktioniert for..of wir können:

1. Machen Sie ein Objekt zu einem Iterierbaren, indem Sie es der mystischen @@ iterator -Eigenschaft über die Symbol.iterator -Eigenschaft zuweisen.

let tempObj = {a:1, b:2, c:3};

tempObj[Symbol.iterator]= () => ({
next: function next () {
return {
    done: Object.keys(this).length === 0,
    value: Object.keys(this).shift()
     }
    }
  })

for(key in tempObj){
 console.log(key)
}
// a
// b
// c

2.Verwenden Sie Object.entries, wodurch ein Iterable zurückgegeben wird:

let tempObj = {a:1, b:2, c:3};

for(let [key, value] of Object.entries(tempObj)) {
    console.log(key, value);
}
// a 1
// b 2
// c 3

3.Verwenden Sie Object.keys, wie folgt:

let tempObj = {a:1, b:2, c:3};
for (let key of Object.keys(tempObj)) {
    console.log(key);
}

// a
// b
// c

Hoffe das hilft!!!!!!

18
Manishz90

Weil das Objektliteral nicht die Eigenschaft Symbol.iterator hat. Um genau zu sein, können Sie nur über String , Array , Map , Set , Argumente , NodeList (nicht allgemein unterstützt) und iterieren Generator mit für ... von Schleife.

Um mit der Objektliteralteration zu arbeiten, haben Sie zwei Möglichkeiten.

für in

for(let key in obj){
    console.log(obj[key]); 
}

Object.keys + forEach

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

Die Antwort ist Nein. For..Of kann nicht mit Objekt-Literalen verwendet werden. 

Ich stimme mit Overv überein, dass For..Of nur für Iterables ist. Ich hatte genau die gleiche Frage, weil ich mithilfe von Objekten Schlüssel und Werte mit for..in durchläuft. Aber ich habe gerade gemerkt, dass ES6 MAPS und SETS dafür sind. 

let test = new Map();
test.set('first', "one");
test.set('second', "two");

for(var item of test) {
  console.log(item); // "one" "two"
}

Daher wird das Ziel erreicht, keine for..In verwenden zu müssen (Validierung mit hasOwnProperty) und keine Object.keys (). 

Darüber hinaus sind Ihre Schlüssel nicht auf Zeichenfolgen beschränkt. Sie können Zahlen, Objekte oder andere Literale verwenden.

2
cuadraman

Objektliterale haben keine integrierten Iteratoren, die für die Arbeit mit for...of-Schleifen erforderlich sind. Wenn Sie jedoch nicht die Mühe haben möchten, Ihren eigenen [Symbol.iterator] zu Ihrem Objekt hinzuzufügen, können Sie einfach die Object.keys()-Methode verwenden. Diese Methode gibt ein Array-Objekt zurück, das bereits über einen integrierten Iterator verfügt, sodass Sie es mit einer for...of-Schleife wie folgt verwenden können:

const myObject = {
    country: "Canada",
    province: "Quebec",
    city: "Montreal"
}

for (let i of Object.keys(myObject)) {
    console.log("Key:", i, "| Value:", myObject[i]);
}

//Key: country | Value: Canada
//Key: province | Value: Quebec
//Key: city | Value: Montreal
2
TheDarkIn1978

Es ist möglich, einen Iterator für jedes gebende Objekt zu definieren. Auf diese Weise können Sie für jedes Objekt eine andere Logik festlegen

var x = { a: 1, b: 2, c: 3 }
x[Symbol.iterator] = function* (){
    yield 1;
    yield 'foo';
    yield 'last'
}

Dann iteriere einfach x

for (let i in x){
    console.log(i);
}
//1
//foo
//last

Es ist möglich, dasselbe mit dem Object.prototype-Objekt zu tun und einen allgemeinen Iterator für alle Objekte zu haben

Object.prototype[Symbol.iterator] = function*() {
    for(let key of Object.keys(this)) {
         yield key 
    } 
 }

dann iteriere dein Objekt so

var t = {a :'foo', b : 'bar'}
for(let i of t){
    console.log(t[i]);
}

Oder so

var it = t[Symbol.iterator](), p;
while(p = it.next().value){
    console.log(t[p])
}
1
Yaki Klein

Ich habe einfach folgendes getan, um meine Sachen leicht zu trösten. 

for (let key in obj) {
  if(obj.hasOwnProperty(key){
    console.log(`${key}: ${obj[key]}`);
  }
}
1
DaFrenzy

Mit Array Destruction können Sie es wie folgt mit forEach iterieren.

const obj = { a: 5, b: 7, c: 9 };

Object.entries(obj).forEach(([key, value]) => {
  console.log(`${key} ${value}`); // "a 5", "b 7", "c 9"
});
0
Nur Rony

in ES6 könnte man mit Generator gehen:

var obj = {1: 'a', 2: 'b'};

function* entries(obj) {
  for (let key of Object.keys(obj)) {
    yield [key, obj[key]];
  }
}

let generator = entries(obj);

let step1 = generator.next();
let step2 = generator.next();
let step3 = generator.next();

console.log(JSON.stringify(step1)); // {"value":["1","a"],"done":false}
console.log(JSON.stringify(step2)); // {"value":["2","b"],"done":false}
console.log(JSON.stringify(step3)); // {"done":true}

Hier ist die jsfiddle. In der Ausgabe erhalten Sie ein Objekt mit den Tasten "value" und "done". "Value" enthält alles, was Sie möchten haben, und "done" ist der aktuelle Status der Iteration in bool.

0
Serge Nikolaev

Wie wäre es mit Object.keys , um ein Array von Schlüsseln zu erhalten? Und dann forEach auf dem Array ?

obj = { a: 1, b:2}
Object.keys(obj).forEach( key => console.log(`${key} => ${obj[key]}`))
0
justingordon

Was ist mit der Verwendung?

function* entries(obj) {
    for (let key of Object.keys(obj)) {
        yield [key, obj[key]];
    }
}

for ([key, value] of entries({a: "1", b: "2"})) {
    console.log(key + " " + value);
}
0
user1703761