Constructors vs Factory Functions!
Tags: javascript, beginners, tutorial, programming
Published: 2022-03-06 15:38:24

## Constructors vs Factory Functions

(before you start look up [objects](https://www.w3schools.com/js/js_objects.asp) if needed, and maybe function [declarations/expressions](https://www.freecodecamp.org/news/when-to-use-a-function-declarations-vs-a-function-expression-70f15152a0a0/))

(all the code for this post is [here](https://codepen.io/QualityPre/pen/BamMdOO)!)

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

```javascript
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](https://www.javascripttutorial.net/javascript-constructor-prototype/) 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?
\
\
\
\
\
\
\

```javascript
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:

```javascript
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.

```javascript
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

1. Forgetting the 'new' keyword (constructor only)
2. Calling a constructor/FF method wrongly
3. Not returning parameters/methods in a factory function

``` javascript
const player = createPlayer() 
```

``` javascript
const playerStats = totalStats()
```
``` javascript
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