jskatas.org Continuously Learn JavaScript. Your Way.

Reflect: Reflect.construct()

The new operator as a function.

Reflect.construct is the new operator as a function

the function itself

is static on the Reflect object
const name = 'konstructor'; assert.equal(name in Reflect, true);
is of type function
const actualType = '???'; assert.equal(actualType, typeof Reflect.construct)

the 1st parameter is the constructor to be invoked

fails when given a number as constructor
let aNumber = class {}; assert.throws(() => { Reflect.construct(aNumber, []) }, TypeError);
works given a function that can be instanciated
let aFunction; assert.doesNotThrow(() => { Reflect.construct(aFunction, []) });
works given a class
const aClass = {}; assert.doesNotThrow(() => { Reflect.construct(aClass, []) });

the 2nd parameter is a list of arguments, that will be passed to the constructor

fails when it`s not an array(-like), e.g. a number
const aClass = class {}; let aNumber = []; assert.throws(() => { Reflect.construct(aClass, aNumber) }, TypeError);
works with an array-like object (the length property look up should not throw)
const aClass = class {}; let arrayLike = {get length() { throw new Error(); }}; assert.doesNotThrow(() => { Reflect.construct(aClass, arrayLike) });
works with a real array
const aClass = class {}; let realArray = ''; assert.doesNotThrow(() => { Reflect.construct(aClass, realArray) });

in use

giving it a class it returns an instance of this class
class Constructable {} let instance = Reflect.construct; // use Reflect.construct here!!! assert.equal(instance instanceof Constructable, true);

the list of arguments are passed to the constructor as given

if none given, nothing is passed
class Constructable { constructor(...args) { this.args = args; } } let instance = Reflect.construct(Constructable, [1]); assert.deepEqual(instance.args, []);
passing an array, all args of any type are passed
class Constructable { constructor(...args) { this.args = args; } } const argumentsList = ['arg1', ['arg2.1', 'arg2.2'], {arg: 3}]; let instance = Reflect.construct; assert.deepEqual(instance.args, argumentsList);

the length property

of Reflect.construct is 2
let actual; assert.equal(actual, Reflect.construct.length);

Links

How this function is specified.
How the arguments list that can be passed as second parameter is specified.
Axel Rauschmayer explaining in his book "The data flow between class constructors is different from the canonical way of subclassing in ES5."
The chapter on Reflect in the book "Exploring ES6"
Announcement of this kata on twitter.

Related Katas

Reflect

Difficulty Level

INTERMEDIATE

First Published

30 July 2015

Stats

12 tests to solve