Start · Sprachen · JavaScript · Referenz · Reflect.apply()

Reflect.apply()

Methode

Ruft die Funktion <code>target</code> mit dem angegebenen <code>this</code>-Wert und einer Argumentliste auf und gibt deren Ergebnis zurück.

seit JavaScript ES2015 Kategorie: method-property

Signatur

Reflect.apply(target, thisArgument, argumentsList)

Beschreibung

Reflect.apply() ist das funktionale Gegenstück zu Function.prototype.apply(). Die Methode ruft eine Funktion mit einem festgelegten this-Wert und einem Array (bzw. einem array-ähnlichen Objekt) von Argumenten auf und gibt das Ergebnis des Aufrufs zurück.

Der große Vorteil gegenüber fn.apply(thisArg, args): Reflect.apply() hängt nicht davon ab, dass die Funktion selbst eine intakte apply-Methode besitzt. Hat eine Funktion eine eigene Eigenschaft apply oder wurde Function.prototype.apply überschrieben, funktioniert Reflect.apply() trotzdem zuverlässig. Damit ersetzt es das umständliche Muster Function.prototype.apply.call(fn, thisArg, args).

Besonders nützlich ist Reflect.apply() in Proxy-Handlern: Die Trap apply hat exakt dieselbe Signatur, sodass man den ursprünglichen Aufruf mit Reflect.apply(target, thisArg, args) sauber weiterleiten kann – etwa für Logging, Zeitmessung oder Validierung.

Parameter

Name Typ Default Beschreibung
$target Pflicht Function Die aufzurufende Zielfunktion. Ist sie nicht aufrufbar, wird ein TypeError ausgelöst.
$thisArgument Pflicht any Der Wert, der beim Aufruf als this verwendet wird. Bei nicht-strikten Funktionen werden null/undefined durch das globale Objekt ersetzt und Primitive in Objekte umgewandelt.
$argumentsList Pflicht Array|ArrayLike Array oder array-ähnliches Objekt mit den Argumenten. Anders als bei Function.prototype.apply() ist dieser Parameter Pflicht – null, undefined oder ein Primitiv lösen einen TypeError aus.

Rückgabewert

Typ
any
Beschreibung
Das Ergebnis des Aufrufs von target mit dem angegebenen this-Wert und den Argumenten.

Beispiele

Grundlegender Aufruf

const zahlen = [4, 17, 9, 42, 3];

// Math.max mit einem Array von Argumenten aufrufen
const maximum = Reflect.apply(Math.max, undefined, zahlen);
console.log(maximum);

// this-Wert gezielt setzen
const text = Reflect.apply(String.prototype.slice, 'programmierung.net', [0, 14]);
console.log(text);
42 programmierung

Robust gegenüber überschriebenem apply

function summe(...werte) {
  return werte.reduce((a, b) => a + b, 0);
}

// Eine Funktion mit eigener apply-Eigenschaft
summe.apply = () => 'überschrieben!';

console.log(summe.apply(null, [1, 2, 3]));
console.log(Reflect.apply(summe, null, [1, 2, 3]));
überschrieben! 6

Aufrufe mit einem Proxy protokollieren

const berechnePreis = (netto, steuersatz) => netto * (1 + steuersatz);

const mitLogging = new Proxy(berechnePreis, {
  apply(target, thisArg, args) {
    const start = performance.now();
    const ergebnis = Reflect.apply(target, thisArg, args);
    const dauer = (performance.now() - start).toFixed(3);
    console.log(`${target.name}(${args.join(', ')}) = ${ergebnis} [${dauer} ms]`);
    return ergebnis;
  }
});

mitLogging(100, 0.19);
berechnePreis(100, 0.19) = 119 [0.012 ms]

Fehlerfall: fehlende Argumentliste

try {
  Reflect.apply(Math.max, null);
} catch (err) {
  console.log(err.constructor.name, '-', err.message);
}

// Mit Function.prototype.apply wäre das erlaubt:
console.log(Math.max.apply(null));
TypeError - CreateListFromArrayLike called on non-object -Infinity

// Wichtig · Fallstricke

  • Argumentliste ist Pflicht: Anders als bei fn.apply(thisArg) führt ein fehlendes oder primitives argumentsList zu einem TypeError. Für einen Aufruf ohne Argumente [] übergeben. Der genaue Wortlaut der Fehlermeldung hängt von der Engine ab.
  • Nicht aufrufbares Ziel: Ist target keine Funktion, wird sofort ein TypeError ausgelöst.
  • Keine Konstruktoraufrufe: Klassen lassen sich mit Reflect.apply() nicht aufrufen (TypeError); dafür gibt es Reflect.construct().
  • Pfeilfunktionen und gebundene Funktionen ignorieren thisArgument – sie behalten ihr lexikalisches bzw. gebundenes this.
  • Große Arrays: Wie beim Spread-Operator gibt es eine engine-abhängige Obergrenze für die Anzahl der Argumente (oft im Bereich von einigen Zehntausend bis wenigen Hunderttausend). Bei sehr großen Datenmengen lieber reduce() verwenden.
  • Oft ist heute fn.call(thisArg, ...args) oder fn(...args) lesbarer; Reflect.apply() glänzt vor allem in Proxys und in Bibliothekscode, der robust gegen manipulierte Prototypen sein muss.
  • Kompatibilität: Wird in allen modernen Browsern und in Node.js ab Version 6 unterstützt; im Internet Explorer nicht verfügbar.