What is prototype in JavaScript?
Tags: javascript
Published: 2020-03-08 09:20:21


![](https://cdn-images-1.medium.com/max/12032/1*YDO_MoZCD4n1CJV3sk_xoQ.jpeg)

JavaScript currently has seven primitives which are: Boolean, Null, Undefined, Number, BigInt, String and Symbol. Everything else is an object— including arrays and dates.

```javascript
const myArr = [];
typof myArr // returns "object"
const yourArr = new Array;
typof yourArr// also returns "object"
```

You’re probably used to using the .slice() or .push() methods often on arrays. Where do these build-in methods come from?

```javascript
const fruits = ['apple', 'peach', 'kiwi'];
fruits.pop(); // removes kiwi
```

They come from the methods of the prototype of the array object you created.

```javascript
const apples = new Array(3).fill('apple');
console.log(Array.prototype); // returns methods of Array prototype
```

When you log the above you will see all the methods that are build-in and ready to use. When you call pop() your are actually calling a function (method) of the prototype object your array is part of. The object that you are calling becomes the value of the this keyword in the method(). So when you do:

```javascript
apples.pop(); // removes and apple
```

the apples array is set as the value of the this keyword. The .slice() method is just a shorthand we are using

```javascript
Array.prototype.pop.call(apples);
```

With call we can borrow methods to use on objects that contain the this keyword (like Array). So actually, we can borrow the pop() method from the Array prototype to use on array-like objects:

```javascript
const fishes = {0: 'Neo', 1: 'Clown', 2: 'Angel', length: 3};
Array.prototype.pop.call(fishes);
```

Object are foundational to almost every aspect of the JavaScript language. The most common way is to create them with curly braces and add properties and methods using dot notation.
```javascript
const fish = {};
fish.name = 'Nemo';
fish.food = 5;
fish.eat = function(food, amount) { 
   console.log(`${this.name} is eating ${food}`);
   this.food += amount
}
```

What if we want to create more fishes? We can place the login inside a function and invoke it when we want to create a new fish.

### Functional Instantiation

```javascript
function Fish(name, food) {
   const fish = {};
   fish.name = name;
   fish.food = food;
   fish.eat = function(food, amount) { 
      console.log(`${this.name} is eating ${food}`);
      this.food += amount
   }
   return fish
}
const nemo = Fish('Nemo', 5);
const angel = Fish('Angel', 5);
```

The eat method is generic, so we are wasting memory by using the above function and making each fish bigger than it needs to be.

### Functional Instantiation with shared methods

```javascript
const fishMethods = {
   eat(food, amount) { 
   console.log(`${this.name} is eating ${food}`);
   this.food += amount
}

}
function Fish(name, food) {
   const fish = {};
   fish.name = name;
   fish.food = food;
   fish.eat = fishMethods.eat
   return fish
}
const nemo = Fish('Nemo', 5);
const angel = Fish('Angel', 5);
```

We’ve solved the problem of memory waste. It still seems a bit weird using a seperate object with methods in order to share methods across instances. Well, that is where prototypes come into place!

Instead of having a seperate object for methods, we call add the methods directly to the prototype of Fish.

### Prototypal Instantiation

```javascript
function Fish(name, food) {
   const fish = {};
   fish.name = name;
   fish.food = food;
   fish.eat = fishMethods.eat
   return fish
}
Fish.prototype.eat = function(food, amount) { 
  console.log(`${this.name} is eating ${food}`);
   this.food += amount
}
const nemo = Fish('Nemo', 5);
const angel = Fish('Angel', 5);
```

Boom! All the functionality is the same, but instead of having to manage a seperate object for all the methods we can just use a built in object from Fish called Fish.prototype.

### Object.create

To improve our code even more, we will using Object.create() to avoid failed lookups. This method creates a new object with the specified prototype.

```javascript
const fish = Object.create(Fish.prototype);
```

### The ‘new’ keyword

When you invoke a function with the new keyword, it automatically assigns the this keyword to the new object that is created. So we do not need to assign the this and return it anymore.

```javascript
function Fish(name, food) {
   // const this = Object.create(Fish.prototype);
   fish.name = name;
   fish.food = food;
   fish.eat = fishMethods.eat
   // return this
}

const nemo = new Fish('Nemo', 5);
const angel = new Fish('Angel', 5);
```

### Classes

A class creates a blueprint for an object, basically the same thing as we just made. There is an easier way to do it and JavaScript isn’t a dead language. So, in 2015, EcmaScript 6 introduced support for Classes and the ‘class’ keyword. How are code looks like with a class:

```javascript
class Fish {
      constructor(name, food) {
      this.name = name;
      this.food = food;
   }
   eat(food, amount) { 
      console.log(`${this.name} is eating ${food}`);
      this.food += amount
   }
}

const nemo = new Fish('Nemo', 5);
const angel = new Fish('Angel', 5);
```

Looks much better, right?

Why is it still helpful to learn how to do it the old way? Because classes are actually *syntactic sugar *over the old way. The class gets converted to the old way!

### Static methods

What if we want a method that we want to use on the class (object constructor) but not in each instance of the class? We just add the static keyword before our method.

```javascript
class Person {
   constructor(name, age) {
      this.name = name;
      this.age = age;
   }
   walk(time) { 
      console.log(`${this.name} is walking for ${time} minutes.`) 
   }
   static sayHi() { 
      alert('Hi!') 
   }
}
const tim = new Person('Tim', 25);
tim.walk(5) // works
tim.sayHi() // does not work
Person.sayHi() // works
```

That’s it, have fun creating objects!