Start · Sprachen · JavaScript · Referenz · Symbol.search

Symbol.search

Eigenschaft

Wohlbekanntes Symbol, über das <code>String.prototype.search()</code> die Suchlogik eines Objekts aufruft – typischerweise <code>RegExp.prototype[Symbol.search]</code>.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Symbol.search

Beschreibung

Symbol.search ist eine statische, nicht beschreibbare Dateneigenschaft von Symbol. Sie enthält das wohlbekannte Symbol @@search. Rufst du str.search(obj) auf und ist obj weder undefined noch null, prüft die Engine, ob obj[Symbol.search] existiert. Wenn ja, ruft sie diese Methode mit dem String als Argument auf und gibt ihr Ergebnis direkt zurück.

Standardmäßig hat nur RegExp.prototype eine solche Methode. Sie sucht nach dem ersten Treffer und liefert dessen Index oder -1. Die Flags g und y werden dabei ignoriert, und lastIndex bleibt nach dem Aufruf unverändert. Gibt es die Methode nicht, wird das Argument mit new RegExp(obj) in einen regulären Ausdruck umgewandelt.

In der Praxis nutzt du Symbol.search auf drei Arten:

  • Du gibst eigenen Klassen eine eigene Suchlogik, zum Beispiel für die Suche ohne Beachtung der Groß-/Kleinschreibung oder für unscharfe Treffer.
  • Du veränderst das Suchverhalten in RegExp-Unterklassen.
  • Du übergibst eine Zeichenkette an search(), ohne dass sie als regulärer Ausdruck gelesen wird.

Es ist ein Symbol-Wert, keine Methode, die du direkt aufrufst. Die Methode dahinter bekommt einen Parameter, nämlich den durchsuchten String, und sollte eine Zahl zurückgeben.

Parameter

Name Typ Default Beschreibung
$string Pflicht string Parameter der Methode obj[Symbol.search](string): der String, auf dem search() aufgerufen wurde.

Rückgabewert

Typ
symbol
Beschreibung
Das wohlbekannte Symbol Symbol.search. Die Methode dahinter sollte eine number zurückgeben: den Index des Treffers oder -1. Eigenschaftsattribute: nicht beschreibbar, nicht aufzählbar, nicht konfigurierbar.

Beispiele

Eigene Suchklasse ohne Beachtung der Groß-/Kleinschreibung

class CaseInsensitiveSearch {
  constructor(term) {
    this.term = term.toLowerCase();
  }
  [Symbol.search](str) {
    return str.toLowerCase().indexOf(this.term);
  }
}

const text = 'Willkommen bei PROGRAMMIERUNG.net';
console.log(text.search(new CaseInsensitiveSearch('programmierung')));
console.log(text.search(new CaseInsensitiveSearch('python')));
15 -1

Zeichenkette wörtlich suchen statt als regulären Ausdruck

const literal = (term) => ({
  [Symbol.search]: (str) => str.indexOf(term)
});

const preis = 'Kosten: 5.99 € (inkl. MwSt.)';
// Ohne Wrapper würde '(inkl.' als ungültiger regulärer Ausdruck einen Fehler werfen
console.log(preis.search(literal('(inkl.')));
console.log(preis.search(literal('5.99')));
13 8

RegExp-Unterklasse, die Suchaufrufe protokolliert

class LoggingRegExp extends RegExp {
  [Symbol.search](str) {
    const index = super[Symbol.search](str);
    console.log(`Suche ${this} in "${str}" → ${index}`);
    return index;
  }
}

const re = new LoggingRegExp('\\d+');
const pos = 'Bestellung Nr. 4711'.search(re);
console.log(pos);
Suche /\d+/ in "Bestellung Nr. 4711" → 15 15

Eingebaute Methode direkt aufrufen und lastIndex prüfen

const re = /a/g;
re.lastIndex = 3;
console.log(re[Symbol.search]('banane'));
console.log(re.lastIndex); // bleibt 3
console.log(typeof Symbol.search, Symbol.search.toString());
1 3 symbol Symbol(Symbol.search)

// Wichtig · Fallstricke

  • Flags g und y wirken nicht: search() liefert immer den ersten Treffer. Mehrere Treffer findest du mit matchAll() oder Symbol.matchAll.
  • lastIndex bleibt erhalten: Die eingebaute Methode speichert lastIndex vorher und stellt ihn danach wieder her. Eigene Umsetzungen in RegExp-Unterklassen sollten sich genauso verhalten.
  • Rückgabewert wird nicht geprüft: search() gibt zurück, was die Methode liefert, auch Werte, die keine Zahl sind. Gib deshalb immer eine Zahl zurück.
  • Symbol.search selbst lässt sich nicht überschreiben, weil die Eigenschaft nicht beschreibbar ist. Du definierst nur Methoden unter diesem Schlüssel.
  • Wird RegExp.prototype[Symbol.search] verändert, betrifft das jeden search()-Aufruf im gesamten Programm. Das ist schlecht für die Performance und riskant, deshalb solltest du es vermeiden.
  • Kompatibilität: ES2015. Funktioniert in allen modernen Browsern und in Node.js 6 und neuer, nicht im Internet Explorer.