Rolf B: Bildauswahl Reset

Beitrag lesen

Hallo Felix,

denn der Index ist ein zweites Argument, (...das nicht stört)

Habe ich auch so nicht gemeint. Ich habe es nur als einen potenziellen Vorteil für .forEach angeführt. Und einen potenziellen Performancenachteil im Nanosekundenbereich.

Es gibt aber Fälle, bei denen man innerhalb einer Schleife gewisse Dinge nicht so einfach tun kann, weil es in einer Schleife selbst keine Closures gibt, was am prozeduralen Kontext liegt.

Das ist falsch. Geschweifte Klammern bilden einen Blockscope für Variablen, die mit let oder const definiert wurden, und mit dem lässt sich eine Closure bilden.

let works = [];
for (let i=0; i<10; i++) {
   works.push(() => i);
}
for (let w of works)
   console.log(w());

Gibt 1 bis 9 aus. Wenn man i dagegen vorher definiert, ist es Teil des äußeren Scopes und man sieht neunmal die 10. Anzumerken ist aber, dass es JS-Bugs gab, bei denen die let-Definition im for-Statement die Schleifenvariable nicht in den Blockscope hineinnahm (siehe bei Kangax ES6, Bindings / let / "for/for-in loop iteration scope").

Ich hätte noch mehr zu sagen, habe jetzt aber keine Zeit mehr.

Und dann tut mir jetzt ja beinah leid, aber ich muss Dir ein Gericht aus deinen eigenen Worten kredenzen. Bitte alles aufessen.

Vorspeise:

for (let i = 0; i < myArray.length; i++) { myArray[i] = false; }
myArray.forEach(element => element = false);

Autsch. Das ist definitiv nicht äquivalent.

  • element ist keine Referenz auf das originale Arrayelement. Wenn Du es überschreibst, bleibt das Array unberührt.
  • Wenn Du ein sparse array[1] hast, füllt die for(;;)-Schleife die Lücken auf. forEach tut das nicht. Hier muss man sich entscheiden, welches von den beiden Verhalten man wünscht.

So würde es gehen, solange man nicht ein sparse array auffüllen muss:

myArray.forEach((element, i, array) => array[i] = false);

Für for...of bräuchte man einen mühseligen Workaround, der zu .forEach() äquivalent wäre:

for (let index of Object.keys(myArray)) { myArray[index] = false; }

Aber das würde ich nicht für empfehlenswert halten.

Hauptgericht:

for (myProperty in myObject) { myObject[myProperty] = false; }
Object.keys(myObject).forEach(myProperty => myObject[myProperty] = false);

Autsch, das ist auch nicht äquivalent. for...in durchläuft auch die Namen der geerbten Propertys. Object.keys() hingegen nicht.

Nachspeise:

for (myValue of myObject) { console.log(myValue); }

listet nicht die Werte aller Objekteigenschaften, sondern bricht ab, wenn myObject ein Objekt ist, das keine Iterator-Schnittstelle anbietet. Da muss schon Object.values(myObject) hin, wenn Du über die Propertywerte iterieren willst (was aber ohne deren Namen nicht sinnvoll ist). Besser wäre für diesem Zweck entries:

for (myEntry of Object.entries(myObject)) {
   console.log(`${myObject[0]} => ${myObject[1]}`);
}

Rolf

--
sumpsi - posui - obstruxi

  1. sparse array:
    let a = [1,2,3];
    a[9]=4;
    Die Indizies 3 bis 8 sind unbesetzt. ↩︎