Constructors vs Factory Functions!
Adam Preece
Posted on March 6, 2022
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
}
}
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)
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}
}
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)
Notice we don't need the new keyword here
We again can access properties by using player2.intelligence etc..
Possible mistakes
- Forgetting the 'new' keyword (constructor only)
- Calling a constructor/FF method wrongly
- Not returning parameters/methods in a factory function
const player = createPlayer()
const playerStats = totalStats()
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()
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
Posted on March 6, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.