Reflect.construct()
The static Reflect.construct()
method acts like the
new
operator, but as a function. It is equivalent to
calling new target(...args)
. It gives also the added option to specify a
different prototype.
Syntax
Reflect.construct(target, argumentsList)
Reflect.construct(target, argumentsList, newTarget)
Parameters
target
- : The target function to call.
argumentsList
- : An array-like object specifying the arguments with which
target
should be called.
- : An array-like object specifying the arguments with which
newTarget
optional- : The constructor whose prototype should be used. See also the
new.target
operator. IfnewTarget
is not present, its value defaults totarget
.
- : The constructor whose prototype should be used. See also the
Return value
A new instance of target
(or newTarget
,
if present), initialized by target
as a constructor with the
given argumentsList
.
Exceptions
A TypeError
, if target
or
newTarget
are not constructors.
Description
Reflect.construct()
allows you to invoke a constructor with a variable
number of arguments. (This would also be possible by using the
spread syntax combined with the
new
operator.)
const obj = new Foo(...args);
const obj = Reflect.construct(Foo, args);
Reflect.construct() vs Object.create()
Prior to the introduction of Reflect
, objects could be constructed using
an arbitrary combination of constructor and prototype by using
Object.create()
.
function OneClass() {
this.name = "one";
}
function OtherClass() {
this.name = "other";
}
// Calling this:
const obj1 = Reflect.construct(OneClass, args, OtherClass);
// ...has the same result as this:
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
// Another example to demonstrate below:
function func1(a, b, c, d) {
console.log(arguments[3]);
}
function func2(d, e, f, g) {
console.log(arguments[3]);
}
const obj1 = Reflect.construct(func1, ["I", "Love", "my", "country"]);
However, while the end result is the same, there is one important difference in the
process. When using Object.create()
and
Function.prototype.apply()
, the new.target
operator will
point to undefined
within the function used as the constructor, since the
new
keyword is not being used to create the object.
When invoking Reflect.construct()
, on the other hand, the
new.target
operator will point to the newTarget
parameter if supplied, or target
if not.
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);
// Logs:
// OneClass
// undefined