Signatur
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
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);
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]));
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);
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));
// Wichtig · Fallstricke
- Argumentliste ist Pflicht: Anders als bei
fn.apply(thisArg)führt ein fehlendes oder primitivesargumentsListzu einemTypeError. Für einen Aufruf ohne Argumente[]übergeben. Der genaue Wortlaut der Fehlermeldung hängt von der Engine ab. - Nicht aufrufbares Ziel: Ist
targetkeine Funktion, wird sofort einTypeErrorausgelöst. - Keine Konstruktoraufrufe: Klassen lassen sich mit
Reflect.apply()nicht aufrufen (TypeError); dafür gibt esReflect.construct(). - Pfeilfunktionen und gebundene Funktionen ignorieren
thisArgument– sie behalten ihr lexikalisches bzw. gebundenesthis. - 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)oderfn(...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.