DEV Community

Cover image for Prototypes & inheritance in JavaScript
vazsonyidl
vazsonyidl

Posted on

Prototypes & inheritance in JavaScript

Intro

Have you ever wondered how inheritance works in a language like Javascript? This language is not in the first ones that come to your mind first when talking about OOP paradigms. Although inheritance literally works in JavaScript, and in the following sections we will discuss it in details.

Prototype, the stalker

If you are not a real newbie to JavaScript, then maybe the words prototype and property not sounds strange. Almost all objects in JavaScript have a prototype object. Although Object.prototype is one of that rare objects that does not have a prototype object. When you create a simple

let a = 'bcd'; code, the

Object.getPrototypeOf(a); // String.prototype

will return you some interesting stuff. Your variable has been wrapped around with an object, here for example with the String. That is the reason why you can use that huge amount of different methods on your variables.

If you create a simple let q = {}; then you do not have a prototype property at all, sou can not query with the q.prototype way. But do not afraid, it is the normal behavior. We will discuss how to inspect the prototype in the following sections.

One important note: almost all object have a prototype but do not have a property called prototype. Although inheritance in JavaScript works even this way.

Prototype chain

Accessing properties of object are just like bubbles underwater. It always goes up and up until reaches its goal.

For example, take that you want to query the myProperty property on an myObject object. If that own property does not exist on that object, the prototype object of myObject is looked up. If the property exists there (on that object), then that is returned. If not, then another level is looked again, until myProperty is found or the prototype property turns out to be null. In this case undefined is returned. As this little description summarized it, the prototype attributes create a chain, called prototype chain.

Example

As you can see here, first we created our base object. Then two descendants are made in a chain-like way. If you query a property it bubbles up in the prototype chain, just like the chair property does. If one is not exists, then undefined returned. As you can see, you can overwrite properties, and that will not affect the prototype chain's properties, so setting properties not bubbles up, only getting.

This is a key feature, because it allows us to create and overwrite inherited properties selectively.

Exceptions

There is one exception that breaks the basic way of creating property of an object. If the inherited property you wish to overwrite (just like color in the previous example) is an accessor property with a setter method. Then that method will be invoked on your object and again, leaves the prototype chain unmodified.

Query the prototype

The simplest built in function to check for the prototype is the

Object.getPrototypeOf()

method.

This is how it works.

Object.getPrototypeOf([]);  // Array.prototype
Object.getPrototypeOf('');  // String.prototype
Enter fullscreen mode Exit fullscreen mode

Another useful method is the isPrototypeOf method. Docs.

It returns a boolean value for you as the name suggests.

let a = {z: 1};
let b = Object.create(a);
a.isPrototypeOf(b);  // return true
Enter fullscreen mode Exit fullscreen mode

Set the prototype

It is important to note, that every prototype is set when creating a new object with any of the available syntaxes and totally unrecommended to change the prototype of an object.
Although it can be carried out in the following way.

let a = [1, 2];
Object.setPrototypeOf(a, String.prototype);
a.join(); // Throws a TypeError, join not defined
Enter fullscreen mode Exit fullscreen mode

That why it is not a recommendation to set prototype manually.

Footnote __proto__

__proto__ is an early browser exposed implementation of the prototype attribute. Because a huge amount of code still depends on it, it is mandated for that reason, but deprecated since a long time. You should really avoid this.

I hope you enjoyed my article, leave your comments below!
The next post will be about Classes & Prototypes.

Resources:
David Flanagan: JavaScript, The Definitive Guide

Top comments (0)