Tücken von JavaScript `for...in`-Schleifen

Die 3-Ausdruck-Form der for-Schleife à la C wird in JavaScript wird oft als altmodisch oder als unbeholfener Anfänger-Stil betrachtet. Manche Entwickler nutzen stattdessen automatisch eine for...of-, foreach- oder for...in-Schleife. Letztere hat jedoch eine Besonderheit, die zu subtilen Fehlern führen kann.

Upper part of a ferris-wheel at night
Photo von Yunus Emre auf Unsplash

Warum sind meine Listenindizes plötzlich Strings?

Dieser kleine JavaScript-Schnipsel soll eine 0-basierte Liste von Indizes in eine 1-basierte Liste umwandeln:

const zeroBased = ['foo', 'bar', 'baz'];

for (const i in zeroBased) {
console.log(${i + 1});
}

Die Ausgabe ist vielleicht nicht das, was du erwartest:

01
11
21

Das wird klarer, wenn du den Code leicht änderst:

const zeroBased = ['foo', 'bar', 'baz'];

for (const i in zeroBased) {
console.log(${i + 1} (${typeof i}));
}

Ausgabe

01 (string)  
11 (string)  
21 (string)  

Es sieht so aus, als würen alle Indizes in Strings umgewandelt und der Operator + addiert nicht,, sondern fügt Strings zusammen.

Aber die Erklärung ist nicht ganz korrekt. Tatsächlich werden keine Indizes in Strings konvertiert. Array in JavaScript sind einfach Objekte und Object-Schlüssel sind immer Strings. String-Schlüssel und numerische Schlüssel lassen sich sogar mischen:

const arr = ['foo', 'bar', 'baz'];
arr['four'] = 'huh?';
console.log(arr['four']); // Ausgabe 'huh?'.
console.log(Array.isArray(arr)); // Ausgabe `true`.
console.log(arr); // Ausgabe `[ 'foo', 'bar', 'baz', four: 'huh?' ]`

In Wirklichkeit unterscheiden sich JavaScript-Arrays von allgemeinen Objekten nur darin, dass für sie zusätzliche Methoden wie map() und filter() definiert sind. Aber die Unterschiede sehen größer aus, als sie sind, weil Funktionen JSON.stringy(), console.log(), console.dir() und Freunde Arrays und Nicht-Array-Objekte unterschiedlich serialisieren und visualisieren.

Oft bleiben die subtilen Probleme, die sich hieraus ergeben, unbemerkt, weil Code, der das ignoriert, einfach funktioniert. Betrachten wir dieses Beispiel:

const zeroBased = ['foo', 'bar', 'baz'];

for (const i in zeroBased) {
console.log(zeroBased[i]);
}

Ausgabe

foo
bar
baz

Die Variable i ist hier immer noch ein String. Wird sie aber als Array-Index verwendet wird, wird sie automatisch in eine Zahl umgewandelt.

Fazit

Wenn du auf Array-Indizes zugreifen möchtest, nutze die 3-Ausdruck-Form der for-Schleife! Sie ist vielleicht weniger prägnant, aber sie ist klarer. Und sie ist effizienter, wenn du die Indizes als Zahlen benötigst, da du dir das Umwandeln der Strings zurück in Zahlen mit parseInt() sparst, was nicht nur hässlich, sondern auch eine Verschwendung von CPU-Zyklen ist.

Leave a comment

JSON.stringify() missbrauchen

Tücken von JavaScript `for...in`-Schleifen

Elektronische Rechnungen mit freier und quelloffener Software erzeugen

Dynamische Angular-Konfiguration

ImageMagick für Perl kompilieren

Angular Tour of heroes als Standalone-App

Diese Website verwendet Cookies und ähnliche Technologien, um gewisse Funktionalität zu ermöglichen, die Benutzbarkeit zu erhöhen und Inhalt entsprechend ihren Interessen zu liefern. Über die technisch notwendigen Cookies hinaus können abhängig von ihrem Zweck Analyse- und Marketing-Cookies zum Einsatz kommen. Sie können ihre Zustimmung zu den vorher erwähnten Cookies erklären, indem sie auf "Zustimmen und weiter" klicken. Hier können sie Detaileinstellungen vornehmen oder ihre Zustimmung - auch teilweise - mit Wirkung für die Zukunft zurücknehmen. Für weitere Informationen lesen sie bitte unsere Datenschutzerklärung.