0

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!

4
  • You want to merge the two objects? you can add properties to JS literal objects just doing obj.property = x; The "dot notation" will try to call a property or method form the object. Commented Apr 28, 2018 at 2:21
  • I don't necessarily want to merge the factories. In some instances I may want to use 1 and other times both. So I need to keep them separate and call them as needed. I know how to add single properties but I'd rather do it with factories. Commented Apr 28, 2018 at 2:23
  • That's too unclear, why and when you would decide it? On creation? Commented Apr 28, 2018 at 2:25
  • Yes when I create the instance sometimes I may want to use 1 factory function, other times I may want to call multiple factory functions. Commented Apr 28, 2018 at 2:26

2 Answers 2

2

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;
}
Sign up to request clarification or add additional context in comments.

Comments

1

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});

3 Comments

Is there a way to encapsulate that into 1 instance instead of both supermarine and test?
Very interesting. Your example used a constructor. It's not possible with a factory function?
nope you can't, prototype needs new and constructor

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.