Signatur
Beschreibung
Symbol.split ist ein sogenanntes bekanntes Symbol (well-known symbol). Ruft man str.split(separator, limit) auf und ist separator weder undefined noch null, sucht die Engine zuerst nach einer Methode separator[Symbol.split]. Gibt es sie, wird sie mit (str, limit) aufgerufen, und ihr Rückgabewert wird direkt zum Ergebnis von split(). Erst wenn diese Methode fehlt, wird das Trennzeichen in einen String umgewandelt und normal getrennt.
Genau so funktioniert das Trennen mit regulären Ausdrücken: RegExp.prototype[Symbol.split] ist die eingebaute Umsetzung, die 'a1b2c'.split(/\d/) möglich macht. Mit diesem Symbol kannst du also eigene Trenn-Objekte schreiben, etwa einen Trenner für mehrere Zeichen, einen CSV-Parser oder eine RegExp-Unterklasse, die ihre Ergebnisse nachbearbeitet.
Die Eigenschaft selbst ist schreibgeschützt: writable: false, enumerable: false, configurable: false. Das Symbol ist in allen Realms (iframes, Worker) dasselbe. Anwendungscode greift selten direkt darauf zu. Es ist vor allem für Bibliotheken und DSL-artige APIs gedacht.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $string Pflicht | string | (Parameter der Methode [Symbol.split]) Der String, auf dem split() aufgerufen wurde. Er ist bereits in einen String umgewandelt. |
|
| $limit | number|undefined | undefined | (Parameter der Methode [Symbol.split]) Das zweite Argument von split(), unverändert durchgereicht. Wurde nichts angegeben, ist es undefined. Die eigene Umsetzung muss es selbst auswerten. |
Beispiele
Das Symbol untersuchen
console.log(typeof Symbol.split);
console.log(Symbol.split.toString());
console.log(typeof RegExp.prototype[Symbol.split]);
Eigener Trenner für mehrere Zeichen
class MehrfachTrenner {
constructor(...zeichen) {
this.zeichen = new Set(zeichen);
}
[Symbol.split](str, limit = Infinity) {
const ergebnis = [];
let aktuell = '';
for (const c of str) {
if (this.zeichen.has(c)) {
ergebnis.push(aktuell);
aktuell = '';
} else {
aktuell += c;
}
}
ergebnis.push(aktuell);
return ergebnis.slice(0, limit);
}
}
const trenner = new MehrfachTrenner(',', ';', ' ');
console.log('rot,grün;blau gelb'.split(trenner));
console.log('rot,grün;blau gelb'.split(trenner, 2));
RegExp-Unterklasse, die Teile trimmt und leere entfernt
class TrimRegExp extends RegExp {
[Symbol.split](str, limit) {
return super[Symbol.split](str, limit)
.map((teil) => teil.trim())
.filter(Boolean);
}
}
const eingabe = ' Apfel , Birne ,, Kiwi ';
console.log(eingabe.split(new TrimRegExp(',')));
Eingebaute Umsetzung direkt aufrufen
const datum = '2024-05-17';
const teile = RegExp.prototype[Symbol.split].call(/-/, datum);
console.log(teile);
// Gleichwertig zu:
console.log(datum.split(/-/));
// Wichtig · Fallstricke
- Um
limitmusst du dich selbst kümmern:split()reicht den Wert ungeprüft durch. Die eingebaute Methode wandelt ihn mitToUint32um (undefinedwird dabei zu 232−1). Eigene Umsetzungen sollten mindestensundefinedsauber behandeln. - Der Rückgabewert wird nicht geprüft: Liefert die Methode kein Array, gibt auch
split()kein Array zurück. Das kann aufrufenden Code überraschen, deshalb besser immer ein Array zurückgeben. nullundundefinedals Trennzeichen lösen keinen Symbol-Aufruf aus.'abc'.split()gibt['abc']zurück.- Built-ins nicht verändern: Eine Methode
String.prototype[Symbol.split]oder ein überschriebenesRegExp.prototype[Symbol.split]ändert das Verhalten global und bremst Engine-Optimierungen aus. Besser eigene Klassen oderRegExp-Unterklassen verwenden. - Die Eigenschaft ist schreibgeschützt: Eine Zuweisung an
Symbol.splitwird ignoriert; im Strict Mode wirft sie einenTypeError. - Unterklassen:
RegExp.prototype[Symbol.split]erzeugt intern überSymbol.specieseinen neuen Regex mit dem Flagy. Unterklassen mit abweichender Konstruktor-Signatur können dabei scheitern. - Kompatibilität: Wird von allen modernen Browsern und von Node.js 6+ unterstützt, nicht aber vom Internet Explorer.