DEV Community

Cover image for Constructors vs Factory Functions!
Adam Preece
Adam Preece

Posted on • Updated on

Constructors vs Factory Functions!

Constructors vs Factory Functions

(before you start look up objects if needed, and maybe function declarations/expressions)

(all the code for this post is here!)

These two elements of Javascript OOP (object-orientated programming) can be very useful to help you orgainse code effectively!

Part 1 - Constructors

Maybe you'd like to duplicate something (say films, books or even a new player in a game).

I would need a blue-print for every new player, say a name, an age, a mood(!?), strength, agilty, intelligence etc. It basically defines all the properties!

Let's make a constructor for a new player

function createPlayer(name,age,mood="content") {
 this.name=name;
 this.age=age;
 this.mood=mood;
 this.strength = Math.floor(Math.random() * 10) + 1;
 this.agility = Math.floor(Math.random() * 10) + 1;
 this.intelligence = Math.floor(Math.random() * 10) + 1;
 this.backgroundStory = function(){
   return `This new brave adventurer is called ${name} and is ${age} years old, ${name} is currently very ${mood}`
 }
 this.totalStats= function(){
     return this.agility + this.intelligence + this.strength
   }  
}

Enter fullscreen mode Exit fullscreen mode

This is a function declaration and using the object literal method I can even add functions to my constructor(backgroundStory and totalStats)

Note you can also you something called prototypes too for defining the method/functions.

Now I can make as many players as I want

How do I do this? By calling the function createPlayer with the parameters?? Try it!
\
\
\
\
\
\
Does it work?
\
\
\
\
\
\
\

const player = new createPlayer("Thor",1000,"grumpy")
console.log(player)
const playerStory = player.backgroundStory()
const playerStats = player.totalStats()
console.log(playerStory,playerStats)


Enter fullscreen mode Exit fullscreen mode

Notice I need the 'new' built in Javascript keyword to call the constructor function.

You can also access the player object properties by using player.name etc

Here I have also declared 2 variables to capture the constructor functions.

Part 2 - Factory Functions

Now, constructors are very useful but some say not to use them as they can be difficult to track down bugs

They look like a function , but they do not behave like one so it can cause many people, especially beginners, headaches (myself included!). It is so very easy to forget the new keyword.

An alternate way to create the above is to use factory functions.

So let us create one, for the above code:

const createPlayerFactory=(name,age,mood="content") =>{
  const strength = Math.floor(Math.random() * 10) + 1;
  const agility = Math.floor(Math.random() * 10) + 1;
  const intelligence = Math.floor(Math.random() * 10) + 1;
  const backgroundStory = () => {
    return `This new brave adventurer is called ${name} and is ${age} years old, ${name} is currently very ${mood}`
  }
  const totalStats = () => strength + agility + intelligence
  // Little ES2015 improvement here,simply creating an object!

  return {name,age,mood,strength,agility,intelligence,backgroundStory,totalStats}
}
Enter fullscreen mode Exit fullscreen mode

This time I have used a function expression with the same parameters.

Notice there is no use of the "this" keyword (hooray!), and we have function expressions for the methods backgroundStory and totalStats.

Also ensure you return what you want to use. Here I have returned everything in an object (you don't need to return everything, as you can keep certain methods/properties private!)

Now how do we access all that wonderful stuff? By simply calling the function.

const player2 = createPlayerFactory("Athena", 235)
console.log(player2)
const playerStory2 = player2.backgroundStory()
const playerStats2 = player2.totalStats()
console.log(playerStory2,playerStats2)
Enter fullscreen mode Exit fullscreen mode

Notice we don't need the new keyword here

We again can access properties by using player2.intelligence etc..

Possible mistakes

  1. Forgetting the 'new' keyword (constructor only)
  2. Calling a constructor/FF method wrongly
  3. Not returning parameters/methods in a factory function
const player = createPlayer() 
Enter fullscreen mode Exit fullscreen mode
const playerStats = totalStats()
Enter fullscreen mode Exit fullscreen mode
const createPlayerFactory=(name,age,mood="content") =>{
  const strength = Math.floor(Math.random() * 10) + 1;
  const agility = Math.floor(Math.random() * 10) + 1;
  const intelligence = Math.floor(Math.random() * 10) + 1;
  const backgroundStory = () => {
    return `This new brave adventurer is called ${name} and is ${age} years old, ${name} is currently very ${mood}`
  }
  const totalStats = () => strength + agility + intelligence

}
const player2 = createPlayerFactory("Athena",235)
const playerStats2 = player2.totalStats()
Enter fullscreen mode Exit fullscreen mode

player2 will be undefined, and any method called will end up in various errors!

Conclusion

We have dicussed two methods of efficient code creation by using a constructor or a factory function.

this is especially poweful as we can create thousands of players by one block of code, thus reducing the chances of code error!

And is there another class way of doing all of the above? That involves a little synthetic sugar!

Thank you for reading,

Quality Pre

Top comments (0)