mzoz
mzoz

Reputation: 1353

Using apply() to chain constructors in JavaScript?

I'm learning apply() in MDN, there's an example I can't figure out:

// Create constructor method for array of args
Function.prototype.construct = function(aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

what does this.apply(oNew, aArgs) do?

Upvotes: 2

Views: 290

Answers (2)

MinimalistYing
MinimalistYing

Reputation: 356

This function is works like the operator new in Javascript.
You can figure out how new works in MDN
For example, if you define an constructor function like below

function Foo(name, age) {
  this.name = name
  this.age = age
}

Foo.prototype.hello = function() {
  console.log('hello' + this.name + this.age)
}

If you already define the Function.prototype.construct like the example you show.
Then you can use either const a = new Foo('a', 1) or const a = Foo.construct('a', 1) to create the same object

And this.apply(oNew, aArgs) is used for call the constructor function to initiate the instance just created

Upvotes: 1

trincot
trincot

Reputation: 350167

First: what would be the aim of this function?

The aim

This prototype function constructor is defined to provide an alternative to new. Where new Person(a,b) will need the arguments as such, this function provides a way to pass those arguments as array.

As a side note: it should be said that the spread syntax makes such a feature unnecessary, as we can pass such an array like so: new Person(...[a,b]). But OK...

Example use

Let's say we have a constructor:

function Person(name, gender) {
    this.name = name;
    this.gender = gender;
}

And I have an array with the arguments:

var args = ["Helen", "F"];

Then we could do:

var person = new Person(args[0], args[1]);

But we want to pass args as single argument. Now this prototype function will help us with that. We can now do:

var person = Person.construct(args);

// Create constructor method for array of args
Function.prototype.construct = function(aArgs) {
  var oNew = Object.create(this.prototype);
  this.apply(oNew, aArgs);
  return oNew;
};

function Person(name, gender) {
    this.name = name;
    this.gender = gender;
}

var args = ["Helen", "F"];

var person = Person.construct(args);

console.log(person);

How does it work

When calling Person.construct(args) the this object will be Person, i.e. our constructor function.

Then the following is done:

var oNew = Object.create(this.prototype);

This will create a Person object, but without actually calling the constructor function Person, so the object is not initialised. It is just an empty object that is an instance of Person.

So we need somehow to call Person with the arguments we have. We can use apply for that:

this.apply(oNew, aArgs);

Recall that this is Person, so we call Person here via apply. apply makes it possible to call a function with a specific this object value (our newly created instance of Person) and the arguments as an array -- exactly what we need.

So the above will initialise our empty object with the name and gender arguments, completing the full creation and initialisation that you would normally have with new.

Upvotes: 4

Related Questions