What the heck is Prototypal Inheritance? Part 1: Object Prototypes
Tags: javascript, webdev, programming, oop
Published: 2022-07-02 10:00:50

_Photo by <a href="https://unsplash.com/@holly_buildalifeyoulove?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Holly Stratton</a> on <a href="https://unsplash.com/s/photos/stack?utm_source=unsplash&utm_medium=referral&utm_content=creditCopyText">Unsplash</a>_

Before you dive in, you should have a decent understanding of [Objects](https://www.programiz.com/javascript/object) and [Functions](https://www.programiz.com/javascript/function) in Javascript.

Prototypes and prototypal inheritance in Javascript can be confusing, especially if you have learned Object Oriented Programming from the perspective of Java or C++.

These posts aim to clear up some of the confusion, and make prototypal inheritance easier to understand.

---

Let's start!

First off, there are two "kinds" of prototypes in Javascript:
1. Object prototypes
2. Function prototypes

Although they both have similarities, it's best to treat them separately. In this article, we will be looking only at Object Prototypes.

Some facts I need you to keep in mind while reading this article:
1. Any data type in Javascript that is not a [primitive](https://developer.mozilla.org/en-US/docs/Glossary/Primitive) is an Object
2. By extension, functions are technically objects in Javascript, albeit with some extra gimmicks, e.g. you can invoke them. [MDN reference](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions)
3. Objects can contain functions as their properties (keys). When functions are part of an object, they are called *methods*. Methods *act* on an object.
```js
// For example
const person = {
	name: 'Luke',
	hello(){
		console.log(`Hello, I am ${person.name}`)
	}
}
person.hello(); // Prints 'Hello, I am Luke'
```
The *this* keyword is deliberately not used in the above example to avoid confusion.

Alright so...

### What is an object prototype?
Let's create an object:
```js
const character = { hearts: 5 }
```

When you create an object in Javascript, it contains the properties you have defined (in this case `character.hearts`). However, this object also has some hidden properties, magically obtained from the Javascript Gods.

For example, if you were to do `character.toString()`, it will print `"[object Object]"`.  You didn't define any `toString()` method inside `character`. So where the heck did it come from?

**Enter the prototype**
Follow along with the steps below to explore this interesting phenomenon:

(1) Open your console (in any browser, I am using Firefox) by pressing F12 > then click on "Console"
(2) Type and enter `window.Object.prototype`. It looks like this:
![window.Object.prototype console output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ajb88ipueyk72mwoqill.png)
We can see that this is an object with a bunch of predefined properties and methods.
(3) Type `const character = {hearts: 1}` and press enter
(4) Type `character` and press enter. The output looks like this:
![character console output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/oei9p0fo87mpihxay4s4.png)
(5) Type `character.__proto__` and press enter. The output looks like this:
![character.__proto__ console output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/drwaetu6s33jvvpf1u69.png)

Keep the console open, and continue reading.

Do the objects at steps (2) and (5) look the same to you, despite being a part of different objects? 

Well guess what, _they are the same_. And we can prove it.

Do this:
(1) Enter `character.toString()`, and observe the output
![character.toString() console output](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/bexsow3i6g3u9gx49bog.png)
(2) Now we will redefine the `toString()` the method defined in `window.Object.prototype`. Enter this in the console: 
```js
window.Object.prototype.toString = () => {console.log('Proved it')}
```
(3) Now, enter `character.toString()` again and check the output
![character.toString() after modification](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vrhne1ybv33l0vc2cgbc.png)

You modified a method that was owned by `window.Object.prototype` and somehow, like spooky action at a distance, your `character.toString()` method's output changed. Crazy stuff right?

This is a good time to pause and review the steps we performed above.
* * *

Time to understand this whole gimmick in depth.

All objects contain a *prototype property*. This "prototype property" is NOT available at  `character.prototype`.  It is, instead, called  `__proto__` and is available as `character.__proto__`. 

The word "prototype" can be confusing. To make things easier to process, you can think of it as "parent" instead. So when you see `character.__proto__`, you can think of it as "parent of `character`".

What do you think will be the parent of `character.__proto__`?
Well, you can chain these! So you can do: `character.__proto__.__proto__`. This time, you will get `null`. 

> `null` is the ultimate ancestor of all Objects.

> Note: `__proto__` is not the standard way to access Object prototypes. The standard way is to do `Object.getPrototypeOf(obj)`, but things are easier to write, explain, and understand when using `__proto__`. Do not use this in production!

The following diagram should help clear a few things up.
![Prototypal inheritance in Javascript](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zv7b2ro4utuaa11rhjr7.png)

As you can see above:
- All Objects in Javascript inherently are nothing, denoted by `null`
- From this nothingness, arises *something* - the most *basic object* you can have -- an object with some default properties, e.g. `toString()`, `valueOf()`. This primal object can be found at `window.Object.prototype` and is defined by the browser
- When you create your own object (any object at all, even an empty object), it *inherits* the properties of this basic object. 
- So if you try to call `character.toString()`, Javascript checks if the method exists on the object `character`. If not, it _drills down_ and checks the parent of `character`, which in this case is the `window.Object.prototype` object.

* * *

According to the Oxford Languages dictionary, the word "prototype" means:
> The first model or design of something from which other forms will be developed.

It's a succinct definition that applies well to the above behavior of prototype. It starts off as nothing and can progressively build up.