Prototype in Javascript
Published: 2021-12-21 05:17:30


![Prototype in Javascript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/a6jt14918mz6if5hbnu2.png)

In this article, we shall discuss prototype in Javascript and how it works under the hood. Often developers who are new to Javascript wonder what is this magic keyword and how the heck it gives access to some methods you never define? Let us find out what prototype is all about.

## Introduction to Javascript prototype

By default, Javascript provides the **Object()** function. You can verify it by printing it in the console.

```jsx
console.log(Object);
```

**output:** 

![Output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/orrbo5w0ogkofvf9zs6b.png)


**Object()** though seems like an object, it's a function and not an object. It might be a little confusing but remember that Object() is a function and it provides an anonymous object that can be referenced using **prototype** keyword.

```jsx
console.log(Object.prototype);
```

**output:**

![output2](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/021xifu6ab6pfbhiyt28.png)

This **Object.prototype** object has predefined methods such as toString() , valueOf(). In JS, when a function is a value of a property of an object, it's called a method.

The **constructor** of Object.prototype, in turn, references the Object function:


![Prototype chaining](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c81qnb26o86dgix99qyk.png)

Let's understand it better using an example. let's define a constructor function called Programmer.

```jsx
function Programmer(name, language) {
this.name = name;
this.language = language;
}
```

The above constructor function accepts name and language as parameters and assigns them to the name and language properties respectively. Behind the scene, JS creates a new function Programmer() and an anonymous object.


![Protoypes in javascript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/uo41g9svqzb60f2jb01i.png)

so similar to what we saw earlier in the case of object function, even this Programmer() function has a property called prototype that references an anonymous object and constructor of which references back to the Programmer() function.

Let us print both in the console and see the output:

```jsx
console.log(Programmer);
```

**Output:**

![prototype chaining](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e7jso1ui0na0nyk5eqk9.png)

```jsx
console.log(Programmer.prototype);
```

**Output:**

![Prototype chaining output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zrls1e41edy64o1526vj.png)

We can observe that the object we get from Programmer.prototype has a constructor that is referencing the Programmer() function itself. In addition to this, JS links the Programmer.prototype to Object.prototype object via **[[ prototype ]],**  this is known as **prototype linkage.**

The Image will help you understand it better:

![Prototypes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/499garz1tq69puwm4xlh.png)

## Defining custom methods in the Javascript prototype

You can define your own custom methods in the prototype object. These custom functions are further accessible to the instances created from that function. 

The following code defines a new method called intro() on Programmer.prototype:

```jsx
Programmer.prototype.intro = function() {
	return "Hello, My name is " + this.name + " and I am a " + this.language + " Developer";
}
```

This intro() function is added to the Programmer.prototype object.


![javascript prototypes](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/cdgxy9jaecpbobx3j5er.png)

Now, let's create an instance of the **Programmer**

```jsx
let p = new Programmer('Jay', 'Python');
```

The JS will now create a new object **p** and links to Programmer.prototype object via the prototype linkage.



Now let's call the intro() function from this **p** instance:

```jsx
let introduction = p.intro();
console.log(introduction);
```

**Output:**

![JS prototype o/p](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/l0obvdke9i0acm3duock.png)

**How does this work?**

Since **p** doesn't have its own intro() method, Javascript follows the prototype linkage and finds it on the **Programmer.prototype** object and executes it.

![prototype](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/7tfyvjuf0o3lntugzido.png)

Now let's try to call **toString( )** method on **p** object.

```jsx
let pString = p.toString();
console.log(pString);
```

**How does this work?**

Again, since **p** doesn't have its own **toString( )** method, Javascript follows the prototype linkage and searches for it on the **Programmer.prototype** object. Because the **Programmer.prototype** doesn't have the **toString( )** ,method, it further follows the prototype linkage and searches in the **Object.prototype** object. It finds **toString( )**  here and executes it:


![Prototype](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/6j0ex58o5kh1uxbqpc3s.png)

If you call a method that doesn't exist up the prototype linkage, i.e. on the **Programmer.prototype** or **Object.prototype,** then Javascript will throw an error that it cannot find the method specified.

```jsx
p.changeProfession();
```

since changeProfession( ); doesn't exist on any of the objects in the prototype chain javascript throws an error.


![prototype in js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/w6oeao0eum6ccti4s85z.png)

let's create another instance called **q:**

```jsx
const q = new Programmer('Raj', 'Javascript');
```

![prototype in js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/e4is1rhn8rtxc3yr0479.png)

Now, **p**  and **q**  both the objects have the same objects and properties. But what if we define another method on **q** ? will p be able to access it ?

The code defines method **getSalary( )** on **q** object.

 ****

```jsx
q.getSalary = function () {
	return "My salary is decent.";
}
```

This **getSalary( )**  method is added to only **q**  object and not on **Programmer.prototype** or **p.**


![Image js](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ishcwgra4g58ts8bn13d.png)

If you try to call **getSalary( )** function with p: it will throw an error:

## The Dunder Proto (_ _ proto _ _)

The __proto__ is pronounced as dunder proto. The **proto** is an accessor property of the Object.prototype object. It exposes the internal prototype linkage ( [[Prototype]]) of an object through which it is accessed.

The p.**proto** exposes the [[Prototype]] that references the Programmer.prototype object.

```jsx
console.log(p.__proto__ === Programmer.prototype); // true
console.log(p.__proto__ === q.__proto__); // true
```

You should, however, use the Object.getPrototypeOf() method instead of the **proto**. The Object.getPrototypeOf() method returns the prototype of a specified object.

```jsx
console.log(p.__proto__ === Object.getPrototypeOf(p)); // true
```

Another popular way to get the prototype linkage when the Object.getPrototypeOf() method wasn’t available is via the constructor property as follows:

```jsx
p.constructor.prototype
```

The `p.constructor` returns programmer, therefore, `p.constructor.prototype` returns the prototype object.

## Shadowing

See the following method call:

```jsx
console.log(p.intro());
```

The p object doesn’t have the intro() method defined, therefore JavaScript goes up to the prototype chain to find it. In this case, it can find the method in the Programmer.prototype object.

Let’s add a new method to the object p with the same name as the method in the Programmer.prototype object:

```jsx
p.intro = function() {
    console.log('Hello');
}
```

And call the **intro( )** method:

```jsx
console.log(p.intro());
```

Because the **p** object has the **intro()** method, JavaScript just executes it immediately without looking it up in the prototype chain.

This is an example of shadowing. The **intro()** method of the **p** object shadows the **intro()** method of the prototype object which the **p** object references.