Prototype in Javascript - 01 - Object creation
Tags: javascript, prototype, objects
Published: 2020-03-19 13:38:06

Javascript has an interesting feature called Prototypal inheritance, which can be used to structure objects in a way that code duplication is minimized. Before we dive deeper into it, let us first try to understand how objects in Javascript are created. 

## Object creation

Objects in Javascript can be created in a number of ways. Let us look at the basic way of creating an object called ***user*** which has a *name* and *score* property attached to it.

```javascript
let user = {
  name: 'Kabir',
  score: 5
}
```

The above code creates an object called ***user*** that has two properties, *name* and *score*, whose values are set to 'Kabir' and 5 respectively. We can verify the same using console.log.

 ```javascript
let user = {
  name: 'Kabir',
  score: 5
}

console.log(user);

// Output: {name: "Kabir", score: 5}
```

Another way of creating objects in Javascript is to create an empty object and set its properties one by one

```javascript
let user = {};
user.name = 'Kabir';
user.score = 5;

console.log(user);

// Output: {name: "Kabir", score: 5}
```

In both of the above examples, we have found a way to create a single ***user*** object whose name is Kabir and score is 5. What if we wished to create another user, say a user with the name John and score 10? The simple way is to create another object as shown below

```javascript
let user = {};
user.name = 'Kabir';
user.age = 5;

let user2 = {};
user2.name = 'John';
user2.score = 10;
```

Although the above method works in the case of only two users, this method won't be feasible when we have to create a lot of users. It would be ridiculous to write code to create a separate object for each user. In such situations, we can use a general function to create users as shown below.

```javascript
function createUser(name, score) {
  let user = {};
  user.name = name;
  user.score = score;
  return user;
} 

let user1 = createUser('Kabir', 5);
let user2 = createUser('John', 10);
```

The above code encapsulates the logic for creating a user in a single function, that can be called anytime we wish to create a new user. Now let us say we wish to add a feature to be able to increase a user's score. We can achieve that by adding a function to the object as shown below.

```javascript
function createUser(name, score) {
  let user = {};
  user.name = name;
  user.score = score;
  user.increaseScore = function() {
    user.score++;
  }
  return user;
} 

let user1 = createUser('Kabir', 5);
console.log(user1.score); // This outputs 5
user1.increaseScore();
console.log(user1.score); // This outputs 6
```

The *increaseScore* function increments the user's score by 1, as seen above. Now, consider a scenario wherein using the *createUser* function, we have created 100 user objects. Each user object will then have 3 properties: 

1. name - A string, indicating the name of the user
2. age - A number, indicating the current score of the user
3. increaseScore - a function, which increments the score of the user by 1

Note that while the value of *name* and *age* may differ in different user objects, the value of *increaseScore* remains the same. It is always a function whose code increments the score of the user by 1.

```javascript
user.increaseScore = function() {
  user.score++;
}
```

Storing a copy of a function that does the exact same thing in every object is not memory efficient. Hence, it would be better if we could write the *increaseScore* function just once and store it somewhere, and later on be able to call that function from any user object, rather than storing an individual copy of the function in every object. In most object-oriented languages, this is achieved by using inheritance. However, Javascript does not support inheritance out of the box. Instead, it has a special feature called prototype which helps us to somewhat implement the concept of inheritance in Javascript. We shall learn more about prototypal inheritance in the next article in this series.