Start · Sprachen · JavaScript · Referenz · Function.prototype.caller

Function.prototype.caller

Eigenschaft

Nicht standardisierte, veraltete Accessor-Eigenschaft, die die Funktion zurückgibt, die die aktuelle Funktion aufgerufen hat, oder <code>null</code>, wenn der Aufruf von oberster Ebene kam.

seit JavaScript Nicht standardisiert (Legacy); in allen gängigen E deprecated seit ja Kategorie: method-property

Signatur

get Function.prototype.caller

Beschreibung

caller ist ein Überbleibsel aus der Frühzeit von JavaScript. Wird die Eigenschaft auf einer Funktion f gelesen, während f gerade ausgeführt wird, liefert sie die Funktion, die f aufgerufen hat. Kam der Aufruf aus Code auf oberster Ebene (Skript oder Modul), ist der Wert null. Früher nutzte man sie für einfaches Debugging oder um „Aufrufketten“ selbst nachzubauen.

Die Eigenschaft gehört nicht zum ECMAScript-Standard. Die Spezifikation legt nur fest, dass Function.prototype einen sogenannten Poison-Pill-Accessor für caller besitzt: Lesen oder Schreiben löst bedingungslos einen TypeError aus. Engines wie V8 und SpiderMonkey geben nicht-strikten, „klassischen“ Funktionen jedoch eine eigene caller-Eigenschaft, die den aufrufenden Kontext zurückgibt. Das gilt nur für Funktionen, die mit function deklariert oder als Ausdruck definiert wurden, und nur außerhalb des Strict Mode.

Für Strict-Mode-Funktionen, Pfeilfunktionen, Methoden-Kurzschreibweisen, Klassen, async-Funktionen und Generatoren gibt es keine eigene Eigenschaft. Dort greift der geerbte Poison-Pill-Accessor, und der Zugriff wirft einen TypeError. Wurde eine nicht-strikte Funktion von einer Strict-Mode-Funktion aufgerufen, liefert caller ebenfalls null, damit keine strikte Funktion nach außen sichtbar wird.

In modernem Code sollte man caller nicht verwenden. Für Debugging eignen sich new Error().stack, console.trace() oder die Entwicklerwerkzeuge des Browsers. Wenn eine Funktion wissen muss, wer sie aufgerufen hat, übergibt man diese Information besser ausdrücklich als Parameter.

Rückgabewert

Typ
Function | null
Beschreibung
Die aufrufende Funktion, solange die Funktion gerade läuft. null, wenn sie von oberster Ebene, von einer Strict-Mode-Funktion oder gerade gar nicht aufgerufen wird. Bei Strict-Mode-Funktionen, Pfeilfunktionen, Klassen, async-Funktionen und Generatoren wirft der Zugriff stattdessen einen TypeError.

Beispiele

Aufrufer in nicht-striktem Code ermitteln

// Klassisches Skript ohne "use strict"
function ziel() {
  if (ziel.caller === null) {
    console.log('Aufruf von oberster Ebene');
  } else {
    console.log(`Aufgerufen von: ${ziel.caller.name}`);
  }
}

function rufer() {
  ziel();
}

rufer();
ziel();
Aufgerufen von: rufer Aufruf von oberster Ebene

TypeError bei Strict Mode und Pfeilfunktionen

const pfeil = () => {};

function strikt() {
  'use strict';
}

for (const fn of [pfeil, strikt]) {
  try {
    console.log(fn.caller);
  } catch (err) {
    console.log(`${fn.name}: ${err.constructor.name}`);
  }
}
pfeil: TypeError strikt: TypeError

Moderne Alternative: Aufrufstapel über Error.stack

const log = (nachricht) => {
  // Zeile 0: "Error", Zeile 1: log selbst, Zeile 2: der Aufrufer
  const zeilen = new Error().stack?.split('\n') ?? [];
  const aufrufer = zeilen[2]?.trim() ?? 'unbekannt';
  console.log(`[${aufrufer}] ${nachricht}`);
};

const speichern = () => log('Daten gespeichert');
speichern();
[at speichern (datei.js:8:25)] Daten gespeichert (Format ist engine-abhängig)

Besser: Kontext ausdrücklich übergeben

const protokolliere = (quelle, nachricht) => {
  console.log(`[${quelle}] ${nachricht}`);
};

const ladeBenutzer = async (id) => {
  protokolliere('ladeBenutzer', `Lade Benutzer ${id}`);
  return { id, name: 'Ada' };
};

ladeBenutzer(42).then((u) => console.log(u.name));
[ladeBenutzer] Lade Benutzer 42 Ada

// Wichtig · Fallstricke

  • Nicht standardisiert und veraltet: Nicht in Produktionscode verwenden. Das Verhalten unterscheidet sich zwischen den Engines, etwa bei Rekursion, eingebauten Funktionen oder bei Aufrufen über eval.
  • Strict Mode: ES-Module und Klassenrümpfe laufen automatisch im Strict Mode. Dort wirft jeder Zugriff auf caller einen TypeError. Das Gleiche gilt für Pfeilfunktionen, Methoden-Kurzschreibweisen, async-Funktionen und Generatoren.
  • Kein echter Aufrufstapel: caller liefert nur eine Funktionsreferenz, keine Stapelrahmen. Bei rekursiven Aufrufen lässt sich mit f.caller.caller keine vollständige Kette rekonstruieren, weil dieselbe Funktion mehrfach vorkommt und die Schleife nicht aufzulösen ist.
  • Performance und Sicherheit: Die Eigenschaft hindert Engines an Optimierungen wie Inlining. Außerdem kann sie Referenzen auf fremde Funktionen offenlegen. Genau deshalb wurde sie im Strict Mode gesperrt.
  • Die verwandte Eigenschaft arguments.callee.caller ist ebenfalls veraltet und im Strict Mode verboten.
  • Als Alternativen eignen sich new Error().stack (Format nicht standardisiert), console.trace() und Haltepunkte in den Entwicklerwerkzeugen.