Start · Sprachen · JavaScript · Referenz · Symbol.for()

Symbol.for()

Methode

Sucht im globalen Symbol-Register nach einem Symbol mit dem Schlüssel <code>key</code> und gibt es zurück – oder legt es neu an, falls es noch nicht existiert.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Symbol.for(key)

Beschreibung

Symbol.for() greift auf das globale Symbol-Register zu, das in der gesamten Laufzeitumgebung gilt. Gibt es dort schon ein Symbol mit dem angegebenen Schlüssel, bekommst du genau dieses Symbol zurück. Gibt es noch keins, wird ein neues angelegt, unter dem Schlüssel eingetragen und zurückgegeben. Mehrere Aufrufe mit demselben Schlüssel liefern also immer dasselbe Symbol.

Darin liegt der Unterschied zu Symbol(): Jeder Aufruf von Symbol("x") erzeugt ein neues, einzigartiges Symbol. Die Beschreibung dient dabei nur zur Fehlersuche. Symbol.for("x") ist dagegen idempotent. Das Register gilt sogar über Realm-Grenzen hinweg, zum Beispiel zwischen iframes, Web Workern mit eigenem Realm oder vm-Kontexten in Node.js.

Typische Einsatzgebiete sind gemeinsame Protokoll-Schlüssel zwischen Modulen, Bibliotheken oder mehrfach geladenen Paketversionen. So markiert React seine Elemente zum Beispiel mit Symbol.for("react.element"). Auch Node.js nutzt Symbol.for("nodejs.util.inspect.custom") für eigene Ausgaben in console.log. Mit Symbol.keyFor() findest du zu einem registrierten Symbol den Schlüssel wieder.

Parameter

Name Typ Default Beschreibung
$key Pflicht string "undefined" Schlüssel, unter dem das Symbol im Register steht. Er dient gleichzeitig als Beschreibung des Symbols. Andere Werte werden in einen String umgewandelt. Ohne Argument wird daraus der String "undefined".

Rückgabewert

Typ
symbol
Beschreibung
Das vorhandene Symbol zum Schlüssel oder, falls es noch keins gibt, ein neu angelegtes und registriertes Symbol.

Beispiele

Symbol.for() im Vergleich zu Symbol()

const a = Symbol.for("app.id");
const b = Symbol.for("app.id");
console.log(a === b);            // gleiches Symbol aus dem Register

const c = Symbol("app.id");
console.log(a === c);            // Symbol() erzeugt immer ein neues Symbol

console.log(a.description);
console.log(Symbol.keyFor(a));   // Schlüssel eines registrierten Symbols
console.log(Symbol.keyFor(c));   // nicht registriert
true false app.id app.id undefined

Gemeinsamer Protokoll-Schlüssel zwischen Modulen

// modul-a.js: markiert Objekte als serialisierbar
const SERIALIZE = Symbol.for("meinprojekt.serialize");

export class User {
  constructor(name) { this.name = name; }
  [SERIALIZE]() { return JSON.stringify({ typ: "user", name: this.name }); }
}

// modul-b.js: braucht keinen Import des Symbols
export const serialize = (obj) => {
  const fn = obj[Symbol.for("meinprojekt.serialize")];
  return typeof fn === "function" ? fn.call(obj) : JSON.stringify(obj);
};

// Verwendung
// console.log(serialize(new User("Anna")));
{"typ":"user","name":"Anna"}

Eigene Ausgabe für console.log in Node.js

const inspect = Symbol.for("nodejs.util.inspect.custom");

class Geld {
  constructor(betrag) { this.betrag = betrag; }
  [inspect]() { return `Geld(${this.betrag.toFixed(2)} €)`; }
}

console.log(new Geld(19.9));
Geld(19.90 €)

// Wichtig · Fallstricke

  • Kein Schutz vor Namenskonflikten: Das Register ist global. Wenn zwei Bibliotheken zufällig denselben Schlüssel verwenden, teilen sie sich das Symbol. Nutze deshalb Schlüssel mit Namensraum, zum Beispiel "firma.paket.zweck".
  • Nicht privat: Jeder Code kann mit demselben Schlüssel an das Symbol kommen. Registrierte Symbole taugen nicht dazu, Daten zu verbergen. Dafür gibt es private Klassenfelder (#feld) oder WeakMap.
  • Registrierte Symbole kann die Speicherbereinigung nicht entfernen. Sie sind deshalb auch nicht als Schlüssel in WeakMap/WeakSet erlaubt (ES2023, führt zu TypeError). Nicht registrierte Symbole aus Symbol() sind dort dagegen zulässig.
  • Bekannte Symbole wie Symbol.iterator stehen nicht im Register: Symbol.keyFor(Symbol.iterator) ergibt undefined.
  • Der Schlüssel wird in einen String umgewandelt: Symbol.for(1) === Symbol.for("1") ergibt true.
  • Kompatibilität: wird seit ES2015 von allen modernen Browsern und Node.js unterstützt, aber nicht vom Internet Explorer.