Factory & Constructor Functions

Factory and constructor functions are possibly the most used and powerful JavaScript patterns around, they are straight forward and easy to reason about whilst promoting modularity. They are very similar in implementation and the benefits of using factories or constructors are also generally speaking the same. A few being:

  • The code is straight forward and easy to reason about.
  • The encapsulated code can be called several times and return new instances of that code or immediately-invoked to a single instance.
  • They can help maintain a clean namespace.
  • Private and Public state is easy to manage and exposes only necessary members.

The difference between the two is fairly subtle but important none the less. Both techniques ultimately create an Object, where a factory function internally creates and returns a new Object a constructor function creates an Object by the method which it is invoked.

Before we begin I think it’s worth noting that factory functions and “The Factory Pattern” are two different concepts as are constructors and constructor functions, these concepts should not be confused.

Factory Functions

You can build an Object up in any way you wish within the function which makes their implementation flexible. As such factory functions can be written in a few different ways, a couple of them are shown below.

The Literal Factory Function

var factoryFn = function () {
    var factoryObj = {};
    var privateProperty = 11;
    factoryObj.property = 1;
    factoryObj.method = function() {
        return 'public method says hello: ' + privateProperty;     
    };
    return factoryObj;
};
// initialise instances of factoryFn
var foo = factoryFn();
// we can now access the members that we returned.
foo.method(); // 'public method says hello: 11'
// and create a whole new instance  
var bar = factoryFn();

The Revealing Factory Function

var factoryFn = function () {
    var privateProperty = 11;
    var method = function() {
        return 'public method says hello: ' + privateProperty; 
    };
    return {
        property: 1,
        method: method
    };
};
// initialise instances of factoryFn    
var foo = factoryFn();
// we can now access the members that we returned.
foo.method(); // 'public method says hello: 11'
// and create a whole new instance  
var bar = factoryFn();

Lets go over the function in detail:

  1. The factoryFn function creates a closure so nothing inside gets leaked into the global scope.
  2. We can create variables and functions inside of that closure that code outside of the functions scope cannot access.
  3. Any members we wish to be publicly accessible outside of the functions closure we add to an Object and then return that Object at the end of the function. We can then store and access those members in a different scope.
  4. Each instance is created simply by invoking the method name.

Constructor Functions

Factory functions get a lot of love these days, though I actually prefer constructor functions. I feel that way because:

  • Using the this keyword gives a strong visual reference as to a members public/private state.
  • Invocation of a constructor is syntactically different from calling other functions, you can tell from the construct that a factory or constructor is being called and it’s not just a normal method.

Generally speaking I find constructor functions more “readable”, and find using coding constructs to increase readability superior to using naming conventions when it’s possible and reasonable to do so. There are a few more cool tricks you can do with constructor functions and this that I will show you in later articles. For now lets just go over the basics.

Traditional Constructor Function initialised with the new operator

var constructorFn = function () {
    var privateProperty = 11;
    this.property = 1;
    this.method = function() {
        return 'public method says hello: ' + privateProperty;    
    };
    return this;
};
//initialise instances of constructorFn
var foo = new constructorFn();
// we can now access the members that we returned.
foo.method(); // 'public method says hello: 11'
// and create a whole new instance  
var bar = new constructorFn();

Traditionally constructor functions are initialised with the new operator, though new is seen by many as a dated technique especially since the introduction of Object.create. Object.create is more idiomatic and appropriate for the intended result.

Object.create makes prototype and delegate prototype inheritance easy to work with, Patterns like Kyle Simpson’s OLOO pattern heavily use this method. Prototypes are a little past the scope of this article and using Object.create does promote their usage so I’m not going to show an example right now, I’ll save that for another day.

Invocation with Function.call or Function.apply

Using Function.call or Function.apply to invoke a constructor function is a little more flexible than using new. The first parameter of Function.call or Function.apply accepts an Object that will define the execution context of this when invoking an instance of the constructor.

var constructorFn = function () {
    var privateProperty = 11;
    this.property = 1;
    this.method = function() {
        return 'public method says hello: ' + privateProperty;    
    };
    return this;
};
//initialise instances of constructorFn    
var foo = constructorFn.call({});
// we can now access the members that we returned.
foo.method(); // 'public method says hello: 11'
// and create a whole new instance  
var bar = constructorFn.call({});

In the above example I have chosen to pass in a new Object each time for simplicity which shows no real advantage or extra flexibility from using new. Although passing in an existing Object can allow for some pretty sweet object compositions which will be explored in a later article.

Passing Arguments with Function.call or Function.apply

Pass in arguments with Function.call by defining them after the first parameter. You can define as many as you like, you’re not limited to two arguments as shown below.

var bar = constructorFn.call({}, arg1, arg2);

Function.apply allows you to pass in arguments as an Array. Check out the respective documentation links below for more information.

var bar = constructorFn.call({}, [arg1, arg2]);

Did you find the article helpful?
Show your ❤ with the click of a button, then tell all your friends.

(If you have liked this article before but find yourself coming back for reference please throw a ❤ my way each time you return and find it of help.)

What do you reckon?

Your email address will not be published. Required fields are marked*

*

!

An error has occured with your submition. Sorry there is no further details, if the problem persists please use the contact form to inform us.