Signatur
Beschreibung
Die Methode handler.construct() ist ein Trap eines Proxy-Handlers. Sie wird aufgerufen, wenn der Proxy mit dem new-Operator instanziiert wird (new proxy(...args)), oder über Reflect.construct(). Ebenso löst ein super(...)-Aufruf in einer abgeleiteten Klasse, deren Elternklasse ein Proxy ist, den Trap aus.
Typische Einsatzgebiete sind Logging und Profiling von Instanziierungen, Validierung von Konstruktor-Argumenten, Singleton- oder Pool-Muster (immer dieselbe Instanz zurückgeben), Dependency Injection sowie das Einschleusen von Standardwerten, ohne die Originalklasse zu verändern.
Wichtig: Damit der Trap überhaupt greift, muss das target selbst konstruierbar sein, also eine interne Methode [[Construct]] besitzen (normale Funktionen, Klassen). Ein Proxy um ein einfaches Objekt oder eine Pfeilfunktion kann nicht mit new aufgerufen werden – es entsteht ein TypeError, noch bevor der Trap läuft.
Um das Standardverhalten innerhalb des Traps auszuführen, nutzt man Reflect.construct(target, argumentsList, newTarget). Durch die Weitergabe von newTarget bleibt die Vererbung (Prototyp der Instanz) auch bei Unterklassen korrekt.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $target Pflicht | Function | Das ursprüngliche Zielobjekt des Proxys. Muss konstruierbar sein (Funktion oder Klasse). | |
| $argumentsList Pflicht | Array | Array mit den Argumenten, die an new übergeben wurden. |
|
| $newTarget Pflicht | Function | Der Konstruktor, der ursprünglich mit new aufgerufen wurde – meist der Proxy selbst, bei Unterklassen die abgeleitete Klasse. Entspricht new.target. |
Rückgabewert
undefined, Zahl, String) zurückgegeben, wirft die Engine einen TypeError.Beispiele
Instanziierungen protokollieren
class User {
constructor(name) {
this.name = name;
}
}
const LoggedUser = new Proxy(User, {
construct(target, args, newTarget) {
console.log(`new ${target.name}(${args.join(', ')})`);
return Reflect.construct(target, args, newTarget);
}
});
const u = new LoggedUser('Anna');
console.log(u instanceof User, u.name);
Konstruktor-Argumente validieren
class Temperature {
constructor(celsius) {
this.celsius = celsius;
}
}
const SafeTemperature = new Proxy(Temperature, {
construct(target, [celsius], newTarget) {
if (typeof celsius !== 'number' || celsius < -273.15) {
throw new RangeError(`Ungültige Temperatur: ${celsius}`);
}
return Reflect.construct(target, [celsius], newTarget);
}
});
console.log(new SafeTemperature(21).celsius);
try {
new SafeTemperature(-300);
} catch (err) {
console.log(err.message);
}
Singleton erzwingen
class Config {
constructor() {
this.createdAt = Date.now();
}
}
const makeSingleton = (Cls) => {
let instance = null;
return new Proxy(Cls, {
construct(target, args, newTarget) {
instance ??= Reflect.construct(target, args, newTarget);
return instance;
}
});
};
const AppConfig = makeSingleton(Config);
const a = new AppConfig();
const b = new AppConfig();
console.log(a === b);
Fehler: Trap gibt keinen Objektwert zurück
const P = new Proxy(function () {}, {
construct() {
return 42; // primitiver Wert – nicht erlaubt
}
});
try {
new P();
} catch (err) {
console.log(err.constructor.name);
}
// Wichtig · Fallstricke
- Rückgabewert muss ein Objekt sein: Anders als bei normalen Konstruktoren wird ein primitiver Rückgabewert nicht ignoriert, sondern führt zu einem
TypeError. Auch ein fehlendesreturn(alsoundefined) löst den Fehler aus. - Ziel muss konstruierbar sein:
new Proxy({}, { construct() { return {}; } })lässt sich nicht mitnewaufrufen. Pfeilfunktionen und Methoden-Kurzschreibweisen haben ebenfalls kein[[Construct]]. newTargetweitergeben: Wernew target(...args)stattReflect.construct(target, args, newTarget)verwendet, verliert bei Unterklassen den richtigen Prototyp –instanceofder Unterklasse liefert dannfalse.thisim Trap ist das Handler-Objekt, nicht die neue Instanz.- Normale Funktionsaufrufe ohne
newwerden nicht vonconstruct, sondern vom Trapapplyabgefangen. - Proxy-Traps kosten Leistung; bei sehr häufigen Instanziierungen in heißen Codepfaden sparsam einsetzen. Proxies lassen sich nicht polyfillen – unterstützt von allen modernen Browsern und Node.js ab Version 6.