Reflect.construct()
Baseline Widely available
This feature is well established and works across many devices and browser versions. It’s been available across browsers since September 2016.
Die Reflect.construct()
-Methode ist eine statische Methode und funktioniert ähnlich wie der new
-Operator, jedoch als Funktion. Sie ist äquivalent zu einem Aufruf von new target(...args)
. Zusätzlich erlaubt sie, einen anderen Wert für new.target
anzugeben.
Probieren Sie es aus
function func1(a, b, c) {
this.sum = a + b + c;
}
const args = [1, 2, 3];
const object1 = new func1(...args);
const object2 = Reflect.construct(func1, args);
console.log(object2.sum);
// Expected output: 6
console.log(object1.sum);
// Expected output: 6
Syntax
Reflect.construct(target, argumentsList)
Reflect.construct(target, argumentsList, newTarget)
Parameter
target
-
Die Ziel-Funktion, die aufgerufen werden soll.
argumentsList
-
Ein array-ähnliches Objekt, das die Argumente angibt, mit denen
target
aufgerufen werden soll. newTarget
Optional-
Der Wert des
new.target
-Ausdrucks innerhalb vontarget
. Standardwert isttarget
. Im Allgemeinen (siehe Beispiel) gibttarget
die Logik zur Initialisierung des Objekts an, währendnewTarget.prototype
das Prototype des erzeugten Objekts angibt.
Rückgabewert
Eine neue Instanz von target
(oder newTarget
, falls vorhanden), initialisiert durch target
als Konstruktor mit der angegebenen argumentsList
.
Ausnahmen
TypeError
-
Wird ausgelöst, wenn
target
odernewTarget
kein Konstruktor ist, oder wennargumentsList
kein Objekt ist.
Beschreibung
Reflect.construct()
bietet die reflektierende Semantik eines Konstruktaufrufs. Das heißt, Reflect.construct(target, argumentsList, newTarget)
ist semantisch äquivalent zu:
new target(...argumentsList);
Beachten Sie, dass beim Einsatz des new
-Operators target
und newTarget
immer denselben Konstruktor darstellen – aber Reflect.construct()
ermöglicht es, einen anderen Wert für new.target
zu übergeben. Konzeptionell ist newTarget
die Funktion, auf der new
aufgerufen wurde, und newTarget.prototype
wird zum Prototype des erzeugten Objekts, während target
der tatsächlich ausgeführte Konstruktor ist, um das Objekt zu initialisieren. Zum Beispiel kann new.target
auch bei Vererbung von Klassen von dem aktuell ausgeführten Konstruktor abweichen.
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {}
new B(); // "B"
Reflect.construct()
erlaubt es, einen Konstruktor mit einer variablen Anzahl von Argumenten aufzurufen. (Dies ist auch mit der Spread-Syntax bei einem normalen Konstruktaufruf möglich.)
const obj = new Foo(...args);
const obj = Reflect.construct(Foo, args);
Reflect.construct()
ruft die interne Methode [[Construct]]
eines Objekts von target
auf.
Beispiele
Verwendung von Reflect.construct()
const d = Reflect.construct(Date, [1776, 6, 4]);
d instanceof Date; // true
d.getFullYear(); // 1776
Ändern von new.target
Wenn newTarget
übergeben wird, ändert dies den Wert von new.target
innerhalb des Konstruktors. Das erzeugte Objekt wird eine Instanz von newTarget
sein, nicht von target
.
function OneClass() {
console.log("OneClass executed");
console.log(`new.target is ${new.target.name}`);
}
function OtherClass() {
console.log("OtherClass executed");
console.log(`new.target is ${new.target.name}`);
}
const obj1 = Reflect.construct(OneClass, []);
// Logs:
// OneClass executed
// new.target is OneClass
console.log(obj1 instanceof OneClass); // true
const obj2 = Reflect.construct(OneClass, [], OtherClass);
// Logs:
// OneClass executed
// new.target is OtherClass
console.log(obj2 instanceof OtherClass); // true
console.log(obj2 instanceof OneClass); // false
Natürlich gibt es keine starke Garantie über die Prototypenkette des erzeugten Objekts, da dies von der Implementierung des Konstruktors abhängt. Zum Beispiel, wenn der target
-Konstruktor ein Objekt zurückgibt, dann wird dieses Objekt das erzeugte Objekt sein, unabhängig vom Wert von newTarget
. Wenn target
ein Proxy mit einer construct
-Falle ist, kontrolliert die Falle vollständig den Konstruktionsprozess.
function OneClass() {
return { name: "one" };
}
function OtherClass() {
return { name: "other" };
}
const obj1 = Reflect.construct(OneClass, [], OtherClass);
console.log(obj1.name); // 'one'
console.log(obj1 instanceof OneClass); // false
console.log(obj1 instanceof OtherClass); // false
Ein gültiges new.target
sollte eine Konstruktorfunktion mit einer prototype
-Eigenschaft sein, aber Letzteres wird nicht erzwungen. Wenn der Wert der prototype
-Eigenschaft kein Objekt ist, wird das initialisierte Objekt von Object.prototype
erben.
function OneClass() {
console.log("OneClass executed");
console.log(`new.target is ${new.target.name}`);
}
function OtherClass() {
console.log("OtherClass executed");
console.log(`new.target is ${new.target.name}`);
}
OtherClass.prototype = null;
const obj = Reflect.construct(OneClass, [], OtherClass);
// Logs:
// OneClass executed
// new.target is OtherClass
console.log(Object.getPrototypeOf(obj) === Object.prototype); // true
Reflect.construct() vs. Object.create()
Vor der Einführung von Reflect
konnten Objekte unter Verwendung einer beliebigen Kombination von Konstruktoren und Prototypen mit Object.create()
erstellt werden.
function OneClass() {
this.name = "one";
}
function OtherClass() {
this.name = "other";
}
const args = [];
const obj1 = Reflect.construct(OneClass, args, OtherClass);
const obj2 = Object.create(OtherClass.prototype);
OneClass.apply(obj2, args);
console.log(obj1.name); // 'one'
console.log(obj2.name); // 'one'
console.log(obj1 instanceof OneClass); // false
console.log(obj2 instanceof OneClass); // false
console.log(obj1 instanceof OtherClass); // true
console.log(obj2 instanceof OtherClass); // true
Das Endergebnis ist zwar dasselbe, aber es gibt einen wichtigen Unterschied im Prozess. Wenn Object.create()
und Function.prototype.apply()
verwendet werden, zeigt der new.target
-Operator innerhalb der Funktion, die als Konstruktor benutzt wird, auf undefined
, da das Schlüsselwort new
nicht verwendet wird, um das Objekt zu erstellen. (Tatsächlich wird die apply
-Semantik verwendet, nicht construct
, obwohl normale Funktionen nahezu gleich funktionieren.)
Bei einem Aufruf von Reflect.construct()
zeigt der new.target
-Operator hingegen auf den newTarget
-Parameter, falls angegeben, oder auf target
, falls nicht.
function OneClass() {
console.log("OneClass");
console.log(new.target);
}
function OtherClass() {
console.log("OtherClass");
console.log(new.target);
}
const obj1 = Reflect.construct(OneClass, args);
// Logs:
// OneClass
// function OneClass { ... }
const obj2 = Reflect.construct(OneClass, args, OtherClass);
// Logs:
// OneClass
// function OtherClass { ... }
const obj3 = Object.create(OtherClass.prototype);
OneClass.apply(obj3, args);
// Output:
// OneClass
// undefined
Spezifikationen
Specification |
---|
ECMAScript® 2025 Language Specification # sec-reflect.construct |
Browser-Kompatibilität
Report problems with this compatibility data on GitHubdesktop | mobile | server | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
construct |
Legend
Tip: you can click/tap on a cell for more information.
- Full support
- Full support