Baseline Widely available
Die statische Methode Reflect.construct()
ist wie der new
Operator, aber als Funktion. Sie ist gleichbedeutend mit dem Aufruf von new target(...args)
. Zusätzlich ermöglicht es die Angabe eines anderen new.target
-Werts.
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 Zielfunktion, 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 von target
. StandardmäÃig target
. Im Allgemeinen (siehe Beispiel) gibt target
die Logik zur Initialisierung des Objekts an, während newTarget.prototype
das Prototyp des konstruierten Objekts spezifiziert.
Eine neue Instanz von target
(oder newTarget
, falls vorhanden), initialisiert durch target
als Konstruktor mit der angegebenen argumentsList
.
TypeError
Wird ausgelöst, wenn target
oder newTarget
kein Konstruktor ist, oder wenn argumentsList
kein Objekt ist.
Reflect.construct()
bietet die reflektive Semantik eines Konstruktoraufrufs. Das heiÃt, Reflect.construct(target, argumentsList, newTarget)
ist semantisch gleichbedeutend mit:
new target(...argumentsList);
Beachten Sie, dass bei Verwendung des new
Operators target
und newTarget
immer derselbe Konstruktor sind â aber Reflect.construct()
ermöglicht es, einen anderen new.target
-Wert zu übergeben. Konzeptionell ist newTarget
die Funktion, bei der new
aufgerufen wurde, und newTarget.prototype
wird das Prototyp des konstruierten Objekts; während target
der Konstruktor ist, der tatsächlich ausgeführt wird, um das Objekt zu initialisieren. Zum Beispiel kann new.target
auch anders sein als der aktuell ausgeführte Konstruktor bei der Vererbung von Klassen.
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {}
new B(); // "B"
Reflect.construct()
ermöglicht es Ihnen, einen Konstruktor mit einer variablen Anzahl von Argumenten aufzurufen. (Dies ist auch mit der Spread-Syntax bei einem normalen Konstruktoraufruf möglich.)
const obj = new Foo(...args);
const obj = Reflect.construct(Foo, args);
Reflect.construct()
ruft die [[Construct]]
interne Objektmethode von target
auf.
const d = Reflect.construct(Date, [1776, 6, 4]);
d instanceof Date; // true
d.getFullYear(); // 1776
Ãndern von new.target
Wenn newTarget
übergeben wird, ändert sich der Wert von new.target
im Konstruktor. Das konstruierte Objekt wird eine Instanz von newTarget
sein, nicht 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 Prototypkette des konstruierten 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 konstruierte Objekt sein, unabhängig vom newTarget
Wert. Wenn target
ein Proxy mit einer construct
Falle ist, dann 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, erbt das initialisierte Objekt von Object.prototype
.
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 mit einer beliebigen Kombination von Konstruktoren und Prototypen unter Verwendung von Object.create()
konstruiert 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
Obwohl das Endergebnis dasselbe ist, gibt es einen wichtigen Unterschied im Prozess. Bei der Verwendung von Object.create()
und Function.prototype.apply()
zeigt der new.target
Operator innerhalb der Funktion, die als Konstruktor verwendet wird, auf undefined
, da das new
Schlüsselwort nicht verwendet wird, um das Objekt zu erstellen. (Tatsächlich verwendet es die apply
-Semantik, nicht construct
, obwohl normale Funktionen fast gleich funktionieren.)
Beim Aufruf von Reflect.construct()
hingegen zeigt der new.target
Operator auf den newTarget
Parameter, falls angegeben, oder auf target
, wenn 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 Browser-Kompatibilität Siehe auch
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4