DR01D
DR01D

Reputation: 1365

Is it possible to use 2 factory functions to populate 1 instance?

Using a single factory function to populate an instance is straightforward. In the example below I use the factory function aircraftFactory() to create a new instance called supermarine. However I'm not sure how to structure this so that both aircraftFactory() and engines() could be used together to create supermarine.

"use strict"

function aircraftFactory(x) {
    return {
        manufacturer: x.manufacturer,
        factory: x.factory
    }
}

function engines(x) {
    return {
        numberOfEngines: x.numberOfEngines,
        costPerEngine: x.costPerEngine
    }
}

let supermarine = aircraftFactory({manufacturer: 'Supermarine', factory: 'Southampton'});

document.querySelector('.output').textContent = supermarine.manufacturer;
<div class='output'></div>

I tried chaining them together like this but it threw an error.

Uncaught TypeError: aircraftFactory(...).engines is not a function

let supermarine = aircraftFactory({manufacturer: 'Supermarine', factory: 'Southampton'}).engines({numberOfEngines: 1, costPerEngine: 35000});

I know there must be a pattern but I can't find an example or figure it out. Thanks for any help!

Upvotes: 0

Views: 98

Answers (2)

John Velasquez
John Velasquez

Reputation: 3451

To extend engines to aircraftFactory you need to use prototype

Prototypes extends/inherit your properties and methods.

Try this

"use strict"

function aircraftFactory(x) {
  this.manufacturer = x.manufacturer;
  this.factory = x.factory;
}

function engines(x) {
    return {
        numberOfEngines: x.numberOfEngines,
        costPerEngine: x.costPerEngine
    }
}

//This is where you extend engines
aircraftFactory.prototype.engines = engines;

//Create the instance of aircraftFactory
let supermarine = new aircraftFactory({manufacturer: 'Supermarine', factory: 'Southampton'}).engines({numberOfEngines: 1, costPerEngine: 35000});

Upvotes: 1

desoares
desoares

Reputation: 861

I think I have a suggestion for you:

function engines(x) {
    return {
        numberOfEngines: x.numberOfEngines,
        costPerEngine: x.costPerEngine
    }
}

If you pass an engine:

function aircraftFactory(x, engine) {
    let aircraft = {
        manufacturer: x.manufacturer,
        factory: x.factory
    };

    if (engine) {
      aircraft.numberOfEngines = engine.numberOfEngines;
      aircraft.costPerEngine = engine.costPerEngine;
    }

    return aircraft;
}

You could create an instance like this:

let aircraft = aicraftFactory(x, engineFactory(y));

But if you want to create the properties without knowing the names:

function aircraftFactory(x, extended) {
    let aircraft = {
        manufacturer: x.manufacturer,
        factory: x.factory
    };

    if (engine) {
        for (let key in extended) {
            aircraft[key] = extended[key];
        }
    }

    return aircraft;
}

Upvotes: 2

Related Questions