Factory Functions in JavaScript




Video transcript and code examples here:
https://medium.com/@mpjme/d38e49802555

Original source


43 responses to “Factory Functions in JavaScript”

  1. BUT, every developer assumes he can take all of the devices' resources for his own, excluding only the operating system. That is definitely wrong. Yes, it typically only matters with thousands of object and thousands of operations etc, but you have to assume that your app is not the only thing running. Plus DOM is slow, and flashy UI's may still carry a significant computing load. It all adds up. So I'm not so sure about the memory usage anti-argument.

  2. You can find the this factory method as Module Pattern in getify's You Dont Know JS (well… really similar)
    https://github.com/getify/You-Dont-Know-JS/blob/master/scope%20%26%20closures/ch5.md#modules
    Ok, so the "private" variables are really nice, that's an absolute plus. On the other hand I like class better. It's cleaner, and with the arrow function I don't think it's really to complicated to solve the "this" problem. Actually the module pattern is more complicated, then using the mentioned arrow functions. You can extend classes, which is another nice feature. Also, since it's only a sugar coating for the prototype pattern you will have the luxury of prototipical inheritance. Aaaand you will use less memory too.
    As with frameworks, you have to find the best solution for the task.

  3. The factory example here is not quite equivalent to the class, because it creates a new closure for every object, so it can be argued to consume more memory. To use prototypes instead, you need to do something like that:

    const dog = sound => {
    const methods = {
    talk: () => console.log(sound)
    }
    return () => Object.create(methods)
    }

    Besides, this factory also has the nice advantage of being more reusable as the sound is not hardcoded anymore.

  4. hey @funfunfunction,

    I really appreciate this video and be convinced by factories.
    I'd like to spread this new way of creating object to my coworker, but I can't find out how functions can call each other.

    For example :
    return {
    talk: () => console.log(sound),
    callMaster: () => {
    talk()
    talk()
    }
    }

    talk will be undefined just as this.talk()

    Maybe I'm missing something basic.

    In hope, you'll answer. :/

  5. I was wondering are you planning to create a paid course so we would have the opportunity to donate? I have never seen a programming video as entertaining, concise yet very clear as yours.

  6. Instead of binding this outside the class at the click handler, can you not also bind this inside the class constructor? Would that be a better option (if you are using classes instead of factories, because reasons)? Like so:
    constructor() …
    this.talk = this.talk.bind(this)

  7. While you've achieved private data with this pattern, it comes with an enormous memory cost. Every time you call your factory function for a new instance, it actually duplicates all those public functions as well, giving fresh copies to each new object. Not a big deal in your small example, but in larger factories called many times to produce many objects, that cost will be gargantuan. Public functions should only be created once and then shared between instances (like they are in stampit's methods({..}) object).

    There is no way to achieve private data without either paying that enormous memory cost, or using ugly hacks like WeakMap that don't suffer memory issues but do have big run-time costs for the hash lookup each time. If you care about memory use and efficiency, private data is currently impossible in JavaScript.

  8. I generally like this channel, but the performance advice was misleading IMO. The cost of instantiation is only one part of the equation, and it doesn't account for the impact on the GC. Heap usage in general will be higher, and you'd see it in slower future collection. That being said, I agree there's a threshold where it doesn't matter. I just think measuring instantiation time isn't the right metric to determine where that threshold is.

  9. Useful video thanks 😁👍 So using the factory method each new dog created would have its own 'sound' private variable? If yes, how would you create a shared variable using a factory function? Could it be through a parameter passed into the factory?

  10. I have done it like this. I guess it is more similar to the factory function than to the class, but it is initialized as a class.

    function Dog () {
    const sound = 'Woof';
    this.talk = () => {
    console.log(sound);
    }
    }

    const sniffles = new Dog();
    sniffles.talk();

  11. the factory function is an example of prototypal inheritance, right? the first object we create is 'dog' with the talk method. we then create 'sniffles', which is an instance of 'dog'. when we call talk on 'sniffles', the method does not exist on 'sniffles', so the Js interpreter looks to it's prototype, which is 'dog', and there it sees the talk method, which can be called by 'sniffles'.

  12. For the below, I need to use the this keyword… (see " this.getOscillatorConfig(oscNumber);). Or is the idea that each composed const should only have 1 function inside? Otherwise, how can I work around this?

    const oscPlayer = (audioContext, voiceConfig) => ({

    getOscillatorConfig(oscNumber)
    {
    return voiceConfig.oscillators[oscNumber];
    },

    getOscillator(oscNumber)
    {
    this.getOscillatorConfig(oscNumber);

    let vco = audioContext.createOscillator();
    vco.type = oscConfig.waveform;

    return vco;
    }
    });

    const Voice = (audioContext, voiceConfig) => {

    return Object.assign(
    {},
    oscPlayer(audioContext, voiceConfig),
    octave()
    )
    }

  13. Correct me if im wrong but another possible way of working around the lexical scope problem with "this" is assigning this into a variable and then using the variable instead like
    let self = this
    self.something = 'something'

    r-right?

  14. What about an instance where I still need to have public properties? For example : Location object which has hash, query, url, host, etc.

    I'd rather avoid writing get functions for all of them, and just have them be accessible right away.

    In general, I can still have a factory, but create the object through Object.create({…}); instead of using thew new operator. But in this case it still instantiates a new object, where the problem with "this" would still exist, as you've shown in your example. I always solve such problems through "bind", or now through =>. But I don't necessarily see it as such a huge problem, even if it does look like a mess.

Leave a Reply