Signatur
Beschreibung
Symbol.matchAll ist ein sogenanntes well-known Symbol, also ein fest eingebautes Symbol. Wenn du str.matchAll(muster) aufrufst, prüft die Engine, ob muster eine Methode unter dem Schlüssel muster[Symbol.matchAll] hat. Falls ja, wird sie mit dem String als Argument aufgerufen, und ihr Rückgabewert (ein Iterator) wird direkt weitergegeben.
Standardmäßig ist diese Methode nur auf RegExp.prototype definiert. RegExp.prototype[Symbol.matchAll](str) kopiert den regulären Ausdruck (über Symbol.species) und liefert einen RegExpStringIterator, der nacheinander alle Treffer mit Gruppen und Index ausgibt.
Das Symbol ist vor allem dann nützlich, wenn du:
- eigene Suchobjekte baust, die sich wie ein regulärer Ausdruck mit
matchAll()verwenden lassen (z. B. Parser, Tokenizer), - in einer Unterklasse von
RegExpdas Trefferformat anpassen willst, - die Iteratorlogik von
RegExpdirekt aufrufen willst, ohne den Umweg über den String.
Die Eigenschaft selbst ist nicht beschreibbar, nicht aufzählbar und nicht konfigurierbar. Symbol.matchAll liefert also immer dasselbe Symbol, auch über verschiedene Realms (iframes) hinweg.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $string Pflicht | string | Parameter der Protokoll-Methode obj[Symbol.matchAll](string): der String, der durchsucht werden soll. String.prototype.matchAll() übergibt hier den String, auf dem sie aufgerufen wurde. Symbol.matchAll selbst ist eine Eigenschaft und nimmt keine Parameter. |
Rückgabewert
Symbol.matchAll. Eine Methode, die unter diesem Schlüssel hinterlegt ist, sollte einen Iterator zurückgeben (z. B. über eine Generator-Funktion).Beispiele
Das Symbol und die eingebaute RegExp-Implementierung
console.log(typeof Symbol.matchAll);
console.log(Symbol.matchAll.toString());
console.log(typeof RegExp.prototype[Symbol.matchAll]);
// Direkter Aufruf, ohne String.prototype.matchAll()
const zahlen = /\d+/g;
const treffer = [...zahlen[Symbol.matchAll]('a1b22c333')].map((m) => m[0]);
console.log(treffer);
Eigenes Suchobjekt für String.prototype.matchAll()
// Ein Objekt ohne RegExp, das lange Wörter findet
const langeWoerter = {
*[Symbol.matchAll](str) {
for (const wort of str.split(/\s+/)) {
if (wort.length > 4) yield wort;
}
}
};
const satz = 'Das ist ein langes Beispiel';
console.log([...satz.matchAll(langeWoerter)]);
RegExp-Unterklasse liefert nur benannte Gruppen
class GruppenRegExp extends RegExp {
*[Symbol.matchAll](str) {
// Standardlogik weiterverwenden, Ergebnis umformen
for (const m of super[Symbol.matchAll](str)) {
yield { ...m.groups };
}
}
}
const query = new GruppenRegExp('(?<key>\\w+)=(?<val>\\w+)', 'g');
const paare = [...'a=1&b=2&c=3'.matchAll(query)];
console.log(JSON.stringify(paare));
// Wichtig · Fallstricke
- g-Flag ist Pflicht: Erkennt
matchAll()das Argument als RegExp (überSymbol.match), wirft es einenTypeError, wenn das Flaggfehlt, und zwar bevor[Symbol.matchAll]aufgerufen wird. Das gilt auch für Unterklassen. - Kein RegExp und keine eigene Methode: Hat das Argument keine Methode
[Symbol.matchAll], wird es pernew RegExp(arg, 'g')umgewandelt. Strings mit Sonderzeichen wie.oder*werden dann als Muster interpretiert. - Rückgabe muss iterierbar sein:
matchAll()prüft den Rückgabewert nicht. Liefert deine Methode keinen Iterator, schlagen erst Spread oderfor...offehl. Am einfachsten ist eine Generator-Methode (*[Symbol.matchAll]). - Kein Zustand am Original: Die eingebaute Implementierung kopiert den RegExp, deshalb bleibt
lastIndexam Original unverändert. Eigene Implementierungen sollten das auch so halten. - Kompatibilität: Unterstützt ab Chrome 73, Firefox 67, Safari 13 und Node.js 12. Ältere Umgebungen brauchen ein Polyfill (z. B. core-js).