Understanding the new keyword in JavaScript
Tags: javascript, beginners, webdev, codenewbie
Published: 2021-06-05 07:16:24

**Hey 👋** this will be a bit long , but detailed post where we will try to understand using an example.

**Assume we have to build a game** where users can register with username against which score would be updated. So, the below code would do the job right?

```javascript
function generateUser(name,score){
  let newUser = {};
  newUser.name = name;
  newUser.score = score;
  return newUser;
}
```

When ever we need to create a new User, we can use `generateUser("<User entered name>" , 0)` which would return us the new user Object.

So, the next thing we need to take into consideration is to increment the score if the user wins the game.

**Obviously, the immediate choice would be to create a new function as below :**

```javascript
function incrementScore(user){
  user.score++;
  console.log(user);
}
```

and whenever we need to increment the score, we can just use this function `incrementScore(user1);`

But the problem here is that, when our code is modular/grows into huge codebase in future, we might not know where the increment function is located and also, in a case where we might need other operations like changing the name or adding a new property , we cannot just keep creating new functions as that would clutter the codebase and would become difficult to maintain.

**So , how do we solve that?**

> Well, in 1 word &#8594; **prototype**.

But lets slowly try to solve this problem by understanding each step.

**What if we could just put the functions inside out generateUser as below?**

```javascript
function generateUser(name,score){
  let newUser = {};
  newUser.name = name;
  newUser.score = score;
  newUser.incrementScore = function() {
  	newUser.score++;
	}
  return newUser;
}
```
By this we can achieve the below :

```javascript
let user1 = generateUser('BruceWayne',10);
user1.incrementScore();
```

Perfect! , now we can just use the user Object itself to incrementScore or change name or whatever...

But, let's consider there are 200 users, in which case it is really painful/in-efficient memory usage to save the `incrementScore` function for every user when we know all it does is incrementScore by 1 and this operation is same across all users.

Turns out we can further optimize this approach using `Object.create()` method as below :

```javascript
function generateUser(name,score){
  let newUser = Object.create(userFunctionsStore);
  newUser.name = name;
  newUser.score = score;
  return newUser;
}

let userFunctionsStore = {
  increment: function() { this.score++ ;}
}

let user1 = generateUser('BruceWayne',10);
console.log(user1); // { name: 'BruceWayne', score: 10 }
user1.increment();
console.log(user1); // { name: 'BruceWayne', score: 11 }

```

**Ohkay! , Bunch of stuff there..**

We have now modified the `generateUser()` to create a new Object using `Object.create()` method instead of `{}`, using which we can now achieve classical inheritance.
More information [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create) do check it out.

So, `Object.create(userFunctionsStore)` means, any and all functions declared inside of `userFunctionsStore` will be accessible by all `newUser` Objects. this is possible because the functions inside `userFunctionsStore` are present in the Object instance of `Object.create` in the prototype property which is present in the global memory space, which is referred by any new `newUser` Objects using a link in \__proto__ property implicitly.

Using this property explicitly is deprecated , more info [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/proto)

Now, the code is looking little better and also more maintainable.

But , there still is a bunch of code that we can avoid, As currently we are creating the prototype bond using `Object.create()` using a `userFunctionsStore` Object , __but we can automate all of that using a keyword `new` as below :__

```javascript
function generateUser(name,score){
  this.name = name;
  this.score = score;
}

generateUser.prototype.increment = function() {this.score++};

let user1 = new generateUser('Bruce Wayne',10);
console.log(user1); // { name: 'Bruce Wayne', score: 10 }
user1.increment();
console.log(user1); // { name: 'Bruce Wayne', score: 11 }

```

We are able to add functions to the prototype of the `generateUser` function explicitly and also we need not create , call , return the object from `generateUser`. And All user Object will be able to access the prototype functions by utilizing prototypal inheritance.

**It's amazing how much stuff the `new` keyword does for us.** Read more about it [here](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/new)

The code now seems perfect. But there are still some changes we can do to make the code more elegant, Since currently to call `generateUser()` the `new` keyword is needed, without which the `this` keyword would point to Global `this`. 
**To solve this we can use a new syntax called `class`.**

Also the best practice is to capitalize the first letter of function when we need to use `new` keyword for calling the function , in this case :

```javascript
function GenerateUser(name,score){
  this.name = name;
  this.score = score;
}

```

## Bonus :- class in JS

Ohkay! , Now we will try to use `class` to replace the `function` as below :

```javascript
class GenerateUser {

}
```

Now we need a function, which to assign the name and score , which we can do in the constructor which is called when we call the class.

```javascript
class GenerateUser{
  constructor(name,score){
    this.name = name;
    this.score = score;
  }
}

let user1 = new GenerateUser('Bruce Wayne' , 10);
console.log(user1); //{ name: 'Bruce Wayne', score: 10 }
```

**As simple as that, looks more clean.**

But now we need to make an `increment()` function which we can directly declare inside a class as below :

```javascript
class GenerateUser{
  constructor(name,score){
    this.name = name;
    this.score = score;
  }
  
  increment() {
    this.score ++;
  }
}

let user1 = new GenerateUser('Bruce Wayne' , 10);
console.log(user1); //{ name: 'Bruce Wayne', score: 10 }
user1.increment();
console.log(user1); //{ name: 'Bruce Wayne', score: 11 }
```

Nothing has changed by using `class` instead of `function`, all the underlying principles are same, as we saw before using function prototypes. Just that the code is more readable and maintainable. And now you know how it works under the hood.

Thanks to Will Sentance and Kyle Simpson for their amazing work.

Let me know if you have any doubts or any issues!.

Thank you 🙏 !