Start · Sprachen · JavaScript · Referenz · String.prototype[Symbol.iterator]()

String.prototype[Symbol.iterator]()

Methode

Gibt einen String-Iterator zurück, der die Zeichenkette Unicode-Codepunkt für Codepunkt durchläuft. Das ist die Grundlage für <code>for...of</code>, Spread-Syntax und <code>Array.from()</code> bei Strings.

seit JavaScript ES2015 Kategorie: method-property

Signatur

String.prototype[Symbol.iterator]()

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

Typ
StringIterator (Iterator<string>)
Beschreibung
Ein neues String-Iterator-Objekt. Jeder Aufruf von 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
H i 👋 5 4

Iterator manuell verwenden

const str = "A😀";
const it = str[Symbol.iterator]();

console.log(it.next());
console.log(it.next());
console.log(it.next());
{ value: 'A', done: false } { value: '😀', done: false } { value: undefined, done: true }

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));
\uDE00\uD83Dcba (defekte Ersatzzeichen) 😀cba 🍕🍔🍟…

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);
4 5 1

// 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 du Intl.Segmenter verwenden.
  • Unterschied zu split(""), str[i] und length: 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 call auf null oder undefined auf, wird ein TypeError ausgelöst.
  • Überschreiben: String.prototype[Symbol.iterator] ist beschreibbar. Wenn man es verändert, ändert sich das Verhalten von for...of und 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 eine for...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.