Why Factory Functions over Constructors

In javascript every function can return an objet (functions in javascript are objects), you do not need the ‘new’ keyword to create objects:

In this example, we create a function that returns a an object with its methods. We do not use ‘new’ or ‘this’.

We we take the same example and use a constructor function this happens:

As we see, we have to use the ‘new’ keyword and the context breaks.

We could fix this with ‘bind’ or arrow functions in ES6;

Here we can start seeing how both patterns significantly show their benefits and drawbacks.

The big problem with inheritance

Aside from being less intuitive and hard to debug ‘inheritance’ posses a bigger problem.

… the really big problem with inheritance is that you’re encouraged to predict the future. Inheritance encourages you to build this taxonomy of objects very early on in your project, and you are most likely going to make design mistakes doing that, because humans cannot predict the future (even though it feels like we can), and getting out of these inheritance taxonomies is a lot harder than getting out of them. Mattias Johansson.

Check Mattias Petter Johansson, post for a deeper understanding on the subject.

Factory functions are widely used

You find in major frameworks and libraries, taken from Eric Elliott’s blog:

  • React `React.createClass()` is a factory.
  • Angular uses classes & factories, but wraps them all with a factory in the Dependency Injection container. All providers are sugar that use the`.provider()` factory. There’s even a `.factory()` provider, and even the`.service()` provider wraps normal constructors and exposes … you guessed it: A factory for DI consumers.
  • Ember `Ember.Application.create();` is a factory that produces the app. Rather than creating constructors to call with `new`, the `.extend()`methods augment the app.
  • Node core services like `http.createServer()` and `net.createServer()` are factory functions.
  • Express is a factory that creates an express app.

Key takeaways

  • Factory functions are more flexible and reusable than classes
  • Factory functions do not need ‘new’ or ‘this’, so lets bugs
  • Constructors classes create tight coupling
  • Constructors would not allow you to expand the root class without refactoring its children
  • Constructors: using ‘instanceof” is not reliable.
  • Choose composition over inheritance

Here are two videos that inspired this post, thanks to Eric Elliott and Mattias Johansson for sharing.