The thing that makes javascript different,  Prototypal inheritance
Tags: javascript, programming, tutorial, webdev
Published: 2020-11-08 09:56:16

Prototypal inheritance, the way that objects inherit from other objects in javascript. If you have been programming in other languages, they usually have class inheritance.
Although js has a class keyword introduced in es6, it's just syntactical sugar. js doesn't really have classes.

Let's try to dig deeper into this,

And before I start discussing prototypal inheritance, I wanna clear some things out in js ...
In js, everything is objects, I mean almost everything, now js has 7 data types, they are
numbers,
booleans,
string,
null,
undefined,
objects,
symbol // introduced new in es6
And all datatypes except objects are primitive types.
Except null and undefined, all js primitive types have wrapper functions, so when you call 'string'.slice(0,8) in js, behind the scenes the code that gets executed :
```javascript
String('string').slice(0,8)
```
Now what about functions and arrays, well let's try to run the following code in the chrome console 
```javascript
typeof [] // object
typeof {} // object
typeof function(){} //function
```
I'll discuss functions later but let's talk about arrays, how they are objects, well arrays are a special kind of object in js.
You can do indexing in arrays and grab intended values.
But from where do you get the push, pop, splice methods in arrays. Well as you know, behind the scenes, our array gets wrapped by the wrapper function Array which exposes us to all these methods...

Now let's talk about functions , how they are objects ...
```javascript
// method 2
function sum(a,b){
 return a+b;
}

//method 2

const sum2 = new Function('a' , 'b' ,'return a+b')

sum(3,2) //returns 5
sum2(3,2) //returns 5
```

You can also create functions with the second method in js,
Also in functions, you can access properties like name and others and do the things that you would do with objects
```javascript
function subtract(a,b){
return a-b
}
subtract.name // returns subtract
```
Well in plain words, functions are special objects which are callable ...


Now we can really dive into prototypal inheritance ...
Well, inheritance is how objects inherit properties and methods from one another 
Try to run the code in the browser
```javascript
const obj = {
a: 'hello', 
b: 'bye'
}
obj1.__proto__ // return Object()
```
The code should return The base object constructor, Why is that
Because in js, objects inherit from the Base Object...
That's why you can use methods in objects like hasOwnProperty, 
isPrototypeOf etc ... We didn't define these methods on our objects ... they got inherited ...
The \__proto__ in js returns the object from which the object is inheriting
But what about arrays and functions,
```javascript
//array
const arr = [1,2,3]
//function
function func(){
 return 0;
}

console.log(func.__proto__)//returns Function()
console.log(arr.__proto__)//returns Array()
```

well in the case of functions and arrays they inherit from the base Function object and the base Array object respectively, 
That's why we can assess methods like map, reduce, filter,foreach, etc. on arrays...Cause they got inherited...
But The base Function and Array Object, do they inherit as well
Let's find out

```javascript
//array
const arr = [1,2,3]
//function
function func(){
 return 0;
}

console.log(Array.__proto__)//returns base Object
console.log(Function.__proto__)//returns base Object
console.log(func.__proto__.__proto__)//returns base Object
console.log(arr.__proto__.__proto__)//returns base Object
```
Well, they inherit from The base Object, __so All of them at the end inherit from the base Object__

Now let's look at the code below
```javascript
//array
const arr = [1,2,3]

console.log(arr.__proto__)//return Base Array object
console.log(Array.prototype)//return Base Array object
```
They both return The base Array object...
**In fact, the \__proto__ actually returns the prototype of the inherited object**,
In this case, our arr inherited from Array, and the arr.\__proto__
actually pointed towards the prototype property of Array or Array.prototype...
So when you create objects, a \__proto__ property is also linked with it which points up the prototype chain...
If you are wondering what's the prototype chain, well it should be easy to understand now, 
```javascript
const arr = [1,2,3]
arr.map(el=> el*2)
```
In the above code snippet, we are mapping through an array and multiplying 2 with every element...
Well, if we console.log arr we should see something like this
![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/jko2sgbz28jkudj7zft2.PNG)
We don't have the map function here, so when javascript fails to fine the map object in the array, javascript goes up the prototype chain, which means it goes to the prototype of Array object, there it finds the map object and thus we can use it...

But what happens if we use a method that is not defined above the prototype chain as well

```javascript
const arr = [1,2,3]
arr.lol(el=> el*2)
```
well arr doesn't have the lol method, so js goes up the prototype chain, and goes to the prototype of the base Array object, there also js doesn't find the map method, so js goes up the prototype chain again, and reaches the prototype of the base Object, there also js doesn't find the map method, so js goes up the prototype chain again, well what do you expect that js found,

```javascript
const arr = [1,2,3]
console.log(arr.__proto__.__proto__.__proto__)//returns null
```
Js found's null, here we go the end of prototype chain, which is the base Object, as everything in js inherits from it if we go up the prototype chain of base Object, javascript returns null, cause null in js means the thing doesn't exist, this is often referenced __null pointer__, in this case, js doesn't go up the prototype chain and returns an error or undefined...
So in one of our code snippets above, when we try to access arr.lol() it's gonna return error...


Now as we understand prototypal inheritance, you may say, how all of this is useful to us...

```javascript
const human = {
 walk(){
console.log('walking....')
} ,
 sleep(){
console.log('sleeping....')
} ,
describe(name){
console.log(`my name is ${name}`)
}
}

const programmer = {
code(){
console.log('coding ...')
}
```

In the above code, we have a human and a programmer object, suppose we want our programmer to walk, sleep and describe himself, cause technically, programmers are human

One way could be to just copy the sleep, walk and describe method and paste in on programmer object, but as programmers, we should never repeat ourselves, This is where prototypal inheritance comes into play, 
We can make programmer object inherit from human 
```javascript
const human = {
 walk(){
console.log('walking....')
} ,
 sleep(){
console.log('sleeping....')
} ,
describe(name){
console.log(`my name is ${name}`)
}
}

const programmer = {
code(){
console.log('coding ...')
}
}

programmer.__proto__ = human
for(const i in programmer){
console.log(i)
}
```

you should get
__code__
__walk__
__sleep__ 
__describe__

So our __programmer__ object is inheriting __walk__ , __sleep__ , describe from __human__ object ...
Another thing we could do is,
```javascript
for(const i in programmer){
if (programmer.hasOwnProperty(i)){
 console.log(i)
}
}
```
you should get
__code__

This only logs __code() method__ , cause the code method  is owned by programmer object , programmer object didn't inherit code method from any other object , so when checking __programmer.hasOwnProperty(i)__, that returned true...


Let's verify that the programmer object is inheriting from human object

```javascript
human.isPrototypeOf(programmer) //returns true
```
Here we use the isPrototypeOf method available on objects to check if human is a prototype of programmer, or does programmer inherit from human 
```javascript
programmer.isPrototypeOf(human) //returns false
```
Here, we are checking the other way around 
We are checking if the programmer is a prototype of human or does human inherit from programmer, 
well human does not inherit from programmer surely,  programmer inherits from human, and thus it returns false



One last thing about prototypal inheritance which is going to be super confusing and shocking and it's going to blow your mind, 
Only functions have the prototype property 💥🤯🤯💥

let's verify that , the base Object,Array , Function are actually functions 
```javascript
typeof Array //Function
typeof Function //Function
typeof Object //Function
```
So they have the prototype property, and our normal arrays, objects don't have the prototype property, I know, super confusing ...

So to review everything in js is an object, everything inherits the base Object in js through prototype chain, we can go up the prototype chain looking for properties on the prototype property, the \__proto__ links higher up to the next prototype change, \__proto__ links the prototype property and only functions have prototype property...

And another thing is that **you shouldn't really use the \__proto__** for inheritance, it's bad for performance and there are many more efficient ways to inherit in js, **one way is Object.create()**

```javascript
const human = {
 walk(){
console.log('walking....')
} ,
 sleep(){
console.log('sleeping....')
} ,
describe(name){
console.log(`my name is ${name}`)
}
}

const programmer = Object.create(human) // does the same thing as programmer.__proto__

programmer.code = () => {
console.log('coding ...')
}

for(const i in programmer){
console.log(i)
}
```

I hope you finally understand what exactly is prototypal inheritance...
If you found this helpful or useful, please share a 💓, 🦄, or 🔖. Thanks!