Signatur
Beschreibung
Symbol.match ist ein sogenanntes bekanntes Symbol (englisch „well-known symbol“). Die Sprache selbst liest diesen Schlüssel an bestimmten Stellen aus. Ruft man str.match(obj) auf, prüft die Engine, ob obj eine Methode unter obj[Symbol.match] hat. Wenn ja, ruft sie diese Methode mit dem String als Argument auf und gibt deren Ergebnis zurück. RegExp.prototype[Symbol.match] enthält den Standard-Algorithmus für reguläre Ausdrücke.
Das Symbol hat zwei Aufgaben:
- Eigene Suchlogik: Jedes Objekt kann eine Methode
[Symbol.match](string)haben. So verhält es sich gegenüberString.prototype.match()wie ein regulärer Ausdruck. Das ist praktisch für eigene Suchobjekte oder fürRegExp-Unterklassen, die das Ergebnis nachbearbeiten. - RegExp-Erkennung (IsRegExp):
String.prototype.startsWith(),endsWith()undincludes()sowie derRegExp-Konstruktor prüfen mitobj[Symbol.match], ob ein Objekt als regulärer Ausdruck gilt. Ist die Eigenschaft wahrheitsähnlich (truthy), werfen die drei String-Methoden einenTypeError. Setzt man sie auffalse, wird einRegExpdort wie ein normaler String behandelt.
Die Eigenschaft selbst ist nicht beschreibbar, nicht aufzählbar und nicht konfigurierbar (writable: false, enumerable: false, configurable: false). Ihr Wert ist in jedem Realm (z. B. auch in iframes) dasselbe Symbol.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $string Pflicht | string | Gilt nur für eine selbst geschriebene Methode unter obj[Symbol.match]: Das ist der String, auf dem match() aufgerufen wurde. Die Engine hat ihn bereits in einen String umgewandelt. |
Rückgabewert
Symbol.match. Eine Methode unter diesem Schlüssel sollte, wie RegExp.prototype[Symbol.match], ein Array mit Treffern oder null zurückgeben. Die Sprache schreibt das aber nicht vor: match() gibt einfach weiter, was die Methode liefert.Beispiele
Eigenes Suchobjekt für String.prototype.match()
class WortSucher {
constructor(wort) {
this.wort = wort.toLowerCase();
}
// Wird von str.match(instanz) aufgerufen
[Symbol.match](str) {
const index = str.toLowerCase().indexOf(this.wort);
if (index === -1) return null;
const treffer = [str.slice(index, index + this.wort.length)];
treffer.index = index;
return treffer;
}
}
const suche = new WortSucher('welt');
console.log('Hallo Welt!'.match(suche));
console.log('Guten Morgen'.match(suche));
RegExp-Unterklasse mit nachbearbeiteten Treffern
class GrossRegExp extends RegExp {
[Symbol.match](str) {
const ergebnis = super[Symbol.match](str);
return ergebnis ? ergebnis.map((s) => s.toUpperCase()) : null;
}
}
const re = new GrossRegExp('ab.', 'g');
console.log('abc xyz abd'.match(re));
RegExp-Prüfung bei startsWith() abschalten
const re = /api/;
try {
'/api/users'.startsWith(re);
} catch (err) {
console.log(err.constructor.name); // TypeError
}
// Kennzeichnung als RegExp entfernen – re wird zu "/api/" umgewandelt
re[Symbol.match] = false;
console.log('/api/users'.startsWith(re));
Symbol untersuchen
console.log(typeof Symbol.match);
console.log(Symbol.match.toString());
console.log(typeof RegExp.prototype[Symbol.match]);
console.log(Object.getOwnPropertyDescriptor(Symbol, 'match'));
// Wichtig · Fallstricke
- Doppelte Rolle: Schon eine truthy Nicht-Funktion unter
Symbol.matchreicht, damit ein Objekt als RegExp gilt.startsWith(),endsWith()undincludes()werfen dann einenTypeError. Umgekehrt entferntre[Symbol.match] = falsediese Kennzeichnung auch bei echten RegExp-Objekten. - RegExp-Konstruktor:
new RegExp(obj)undRegExp(obj)werten ebenfallsobj[Symbol.match]aus. Deshalb kann ein Objekt mit gesetztemSymbol.matchdort unerwartet als Muster-Quelle behandelt werden (Zugriff aufsource/flags). - Fallback: Hat das Argument von
match()keine Methode[Symbol.match], wird es innew RegExp(arg)umgewandelt. Aus einem normalen String wird also ein Muster. Sonderzeichen wie.oder?bekommen dann eine Bedeutung. - Nur
match():String.prototype.matchAll()nutzt ein eigenes Symbol, nämlichSymbol.matchAll. Ebenso nutzenreplace(),search()undsplit()jeweilsSymbol.replace,Symbol.searchundSymbol.split. - Kompatibilität: Wird seit ES2015 in allen modernen Browsern und in Node.js unterstützt. Der Internet Explorer kennt das Symbol nicht, und ohne Engine-Unterstützung lässt es sich nicht vollständig nachrüsten (kein vollständiges Polyfill möglich).