Start · Sprachen · JavaScript · Referenz · Symbol.match

Symbol.match

Eigenschaft

Das bekannte Symbol <code>Symbol.match</code> legt fest, welche Methode <code>String.prototype.match()</code> aufruft. Außerdem kennzeichnet es Objekte als reguläre Ausdrücke.

seit JavaScript ES2015 – Baseline: alle modernen Browser, Node.js Kategorie: method-property

Signatur

Symbol.match

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über String.prototype.match() wie ein regulärer Ausdruck. Das ist praktisch für eigene Suchobjekte oder für RegExp-Unterklassen, die das Ergebnis nachbearbeiten.
  • RegExp-Erkennung (IsRegExp): String.prototype.startsWith(), endsWith() und includes() sowie der RegExp-Konstruktor prüfen mit obj[Symbol.match], ob ein Objekt als regulärer Ausdruck gilt. Ist die Eigenschaft wahrheitsähnlich (truthy), werfen die drei String-Methoden einen TypeError. Setzt man sie auf false, wird ein RegExp dort 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

Typ
symbol
Beschreibung
Das bekannte Symbol 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));
[ 'Welt', index: 6 ] null

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));
[ 'ABC', 'ABD' ]

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));
TypeError true

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'));
symbol Symbol(Symbol.match) function { value: Symbol(Symbol.match), writable: false, enumerable: false, configurable: false }

// Wichtig · Fallstricke

  • Doppelte Rolle: Schon eine truthy Nicht-Funktion unter Symbol.match reicht, damit ein Objekt als RegExp gilt. startsWith(), endsWith() und includes() werfen dann einen TypeError. Umgekehrt entfernt re[Symbol.match] = false diese Kennzeichnung auch bei echten RegExp-Objekten.
  • RegExp-Konstruktor: new RegExp(obj) und RegExp(obj) werten ebenfalls obj[Symbol.match] aus. Deshalb kann ein Objekt mit gesetztem Symbol.match dort unerwartet als Muster-Quelle behandelt werden (Zugriff auf source/flags).
  • Fallback: Hat das Argument von match() keine Methode [Symbol.match], wird es in new 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ämlich Symbol.matchAll. Ebenso nutzen replace(), search() und split() jeweils Symbol.replace, Symbol.search und Symbol.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).