Signatur
Beschreibung
Mit der Methode [Symbol.iterator]() erfüllen String-Werte das iterierbare Protokoll. Überall, wo JavaScript ein iterierbares Objekt erwartet, kann man deshalb direkt einen String verwenden. Dazu gehören for...of, die Spread-Syntax [...str], Array.from(), Destrukturierung, new Set(str) und Promise.all(). Die Methode wird in der Praxis fast nie direkt aufgerufen. Die Sprache ruft sie automatisch auf.
Der zurückgegebene String-Iterator liefert die Zeichenkette nach Unicode-Codepunkten, nicht nach UTF-16-Codeeinheiten. Ersatzpaare (Surrogate Pairs) wie bei Emojis oder seltenen CJK-Zeichen bleiben dadurch als ein Element erhalten. Genau hier liegt der Unterschied zu str.split(""), zum Indexzugriff str[i] und zu str.length: Diese arbeiten alle mit Codeeinheiten.
Die Methode eignet sich, wenn man Zeichen „echt“ zählen, umdrehen oder einzeln verarbeiten will. Ein Codepunkt ist aber nicht immer das, was ein Mensch als ein Zeichen wahrnimmt (Graphem). Kombinierte Emojis (z. B. Familien- oder Hautfarben-Emojis mit ZWJ) und Buchstaben mit kombinierenden Akzenten bestehen aus mehreren Codepunkten. Für diese Fälle ist Intl.Segmenter das richtige Werkzeug.
Rückgabewert
next() liefert { value: string, done: boolean }, wobei value genau einen Unicode-Codepunkt enthält (1 oder 2 UTF-16-Codeeinheiten). Der Iterator ist selbst iterierbar.Beispiele
Codepunkte mit for...of durchlaufen
const gruss = "Hi 👋";
for (const zeichen of gruss) {
console.log(zeichen);
}
// Vergleich: Länge in Codeeinheiten vs. Codepunkten
console.log(gruss.length); // UTF-16-Einheiten
console.log([...gruss].length); // Codepunkte
Iterator manuell verwenden
const str = "A😀";
const it = str[Symbol.iterator]();
console.log(it.next());
console.log(it.next());
console.log(it.next());
String sicher umkehren und kürzen
const reverse = (s) => [...s].reverse().join("");
const truncate = (s, max) => {
const chars = Array.from(s);
return chars.length > max ? chars.slice(0, max).join("") + "…" : s;
};
console.log("abc😀".split("").reverse().join("")); // kaputt
console.log(reverse("abc😀"));
console.log(truncate("🍕🍔🍟🌭🍿", 3));
Eindeutige Zeichen zählen und Graphem-Grenzen
const text = "Mississippi";
console.log(new Set(text).size); // eindeutige Codepunkte
// Grenze: ZWJ-Emoji besteht aus mehreren Codepunkten
const familie = "👨👩👧";
console.log([...familie].length);
const seg = new Intl.Segmenter("de", { granularity: "grapheme" });
console.log([...seg.segment(familie)].length);
// Wichtig · Fallstricke
- Codepunkte statt Grapheme: Der Iterator trennt nach Unicode-Codepunkten. Kombinierte Zeichen fallen dabei auseinander, etwa
"e\u0301"(é), Flaggen, Hautfarben-Modifikatoren oder ZWJ-Sequenzen. Für benutzersichtbare Zeichen solltest duIntl.Segmenterverwenden. - Unterschied zu
split(""),str[i]undlength: Diese arbeiten mit UTF-16-Codeeinheiten und können Ersatzpaare zerschneiden. - Einzelne Ersatzzeichen: Ein alleinstehendes Ersatzzeichen (Lone Surrogate) wird als eigenes Element geliefert. Es wird nicht ersetzt und löst keinen Fehler aus.
- Primitive Werte: Beim Aufruf auf einem String-Primitiv wird dieser automatisch in ein Objekt verpackt (Autoboxing). Ruft man die Methode über
callaufnulloderundefinedauf, wird einTypeErrorausgelöst. - Überschreiben:
String.prototype[Symbol.iterator]ist beschreibbar. Wenn man es verändert, ändert sich das Verhalten vonfor...ofund Spread bei allen Strings. Davon ist dringend abzuraten. - Performance: Bei sehr langen Strings erzeugt
[...str]ein großes Array. Für eine reine Zählung ist einefor...of-Schleife mit Zähler speichersparender. - Kompatibilität: Wird in allen modernen Browsern und in Node.js ab Version 0.12 unterstützt (Baseline). Der Internet Explorer unterstützt die Methode nicht.