Prototype in JavaScript

Prototype in JavaScript

Let's understand prototype with a question

Let's just say I have a really simple method or string here that, hey I want to simply have some functionality so I am going to say

let myName = "Sudhanshu"

Notice here how many characters are there What is the length of this string, yes The length of this string is 9.

let myName = "Sudhanshu   "

but what I am saying is 9 is the length and after adding 3 white spaces, what is the length of this string, the total length became 12 and I can verify that by

console.log(myName.length)

// output
12

This has the property of length and it gives me 12 but I don't want 12 I want additional functionality so if somebody uses my framework I can do the dom-manipulation, Similarly I want to have a very basic rule here that if somebody uses this I want to use the actual length something like a property or a function should be there that is trueLength(), just like this and it should give me the actual length of this one.

And I know a lot of you will know string you will use the trim method and all these things but I want this functionality to be dug into default datatypes, something like a string in your framework this is possible and similar concepts are used when you try to manipulate the dom, What javascript is doing is trying to manipulate the elements of the web, so I hope you are getting this.

so sometimes you want to show the button sometimes you want to hide the button entirely from the dom This all is a dom-manipulation, what react is doing is taking those buttons or those cards out of the dom or injecting them back, This is all dom manipulation.

so if you understand this core syntax you will at least know how the basic manipulations are done and how this whole concept can be taken for years and you design your own libraries, frameworks, or something like that.

Okay, I hope you understand what is our goal, and for this goal, we are going to do the entire study.


Okay, one more thing that you should know,

Let's go ahead and declare some of the arrays

let myHeroes = ["Ram", "Hanuman"]

Okay really basic, nothing complex we have done here

As we run this in the browser console

We see this, and its datatype is an array, and when we open this up

It gives me that there are two values in this array, the first one being "Ram" or the 0th value, the 1st value is "Hanuman" and there is a length property here

so length property what it does, I can access this, just like this I can say

and it gives me the length of the array

but now if I see this, this prototype is also available to me now from where this came from Actually, we never said that hey this is we designed an array, we never said that it is going to be like having this prototype property since look at the code we never said that this should have a property or something like that as a prototype

So there is something that is giving this prototype and When we open this up

I see that there are so many options up here, some of them are very very familiar something like indexOf something like map very common and popular we have push we have pop we have unshift So these are the common properties we studied when we studied the array.

so there is something that is giving some additional functionality or we can call them in our terms a superpower. some superpowers to these superhuman or superheroes, we never said that there should be a concat, so these properties might be coming up from somewhere no these are not coming up from the window, these are coming up from the prototype.

On the object we studied that everything is an object and an object has some default properties and these default properties if somebody is inheriting these things from the object itself that is exactly what is happening here, arrays inherit some properties from the objects and these properties are being injected in the prototype

Today we are going to study more about how we can actually inject some of our own customized property in these prototypes so that our goal can be achieved

The goal is simple We want to have a trueLength of a string, okay so now let's see how this can be done

Let's just say this is my code, so now notice here I am defining a classic object with nothing to worry about

let heroPower = {
    Ram: 'arrow',
    Hanuman: 'ashta siddhi',
    getHanumanPower: function(){
        console.log(`Hanuman power is ${this.Hanuman}`);
    }
}

right now you should not worry about where the prototype is coming up or how that is coming up no nothing don't worry about this

This is the most common and one of the easiest of the superpowers, we have defined two properties and one method deliberately, I have defined this because in the prototype we saw that some of them were methods some of them were strings, and all of that so what is allowed and what is not allowed we have to study that

notice here from the object we studied something that I can actually go ahead and say, there were so many of the properties that we studied it, one of them is actually prototype we studied that we can actually put some attributes, get some attributes and all of that

One of the other things is the prototype, now What I am doing is naming the prototype as sudhanshu

Object.prototype.sudhanshu = function(){
    console.log("Sudhanshu is present in all objects");
}

It could be anything the reason why I am naming it sudhanshu that you understand clearly it could be named anything at all and then we are defining a function in it and this function simply says that Sudhanshu is present in all objects

The impact of this line is very very heavy This is the most precious line that we have written so far, What is the impact of this line Notice here that there are arrays myHeroes = ["Ram", "Hanuman"]

Now listen to this very carefully I have this array myHeroes Can I access this sudhanshu here as a function Obviously because I have defined this as a function, is this now possible

myHeroes.sudhanshu()

// output
Sudhanshu is present in all objects

Yes absolutely correct It is possible, how it was possible remember we are now directly targetting the top of the chain, what is the top of the chain in javascript, it is objects.

Arrays are also inhering from the objects or any other objects are also inheriting from objects, and classes even are also inhering from the object, so we target directly the objects

When I am directly targetting an object and I am accessing its prototype I came to know while analyzing the array that even whatever you define if there is a drop-down there then I can access the prototype there

So I am saying hey I want to give access to that property and in that, adding a property sudhanshu and sudhanshu is a function so whoever is inheriting from the object gets this property

Let's go and check in the browser console

As soon as I came in it says Sudhanshu is present in all objects because the browser is also doing it

Just to understand it a little bit more, we saw myHeroes is available to me, I clicked and opened this up I saw that the 0th element is 'Ram' the 1st element is 'Hanuman', and the length is there

but what do you expect when I open up this prototype, In terms of any elements that we have added here

So If I open this up can you see whether sudhanshu is present here or not, it's not but if I open this up further

You can see this sudhanshu

Now let's analyze what has happened here and why we are not able to see up there.

Let's analyze What is happening and yes this topic is sometimes called prototypal chaining.

Okay, what we did was we designed an array and we also designed an object, this was designed to just make sure that you understand the object part.

So we saw that whenever we say myHeroes There are some properties of the array like length, 0th element, and 1st element and there is a default prototype there

So if I go ahead and say

So we saw that by default there is some property length and there is already a property available so whose prototype is this, this is the array's prototype

If I go up further

There is still a prototype whose prototype is this, this is the object's prototype, so arrays are inheriting from the object and when we open it further you see that

There is no prototype here, So the final conclusion is object is parent to all.

Now coming back to this code

let myHeroes = ["Ram", "Hanuman"]

Object.prototype.sudhanshu = function(){
    console.log("Sudhanshu is present in all objects");
}
myHeroes.sudhanshu()

Where do you expect now that in myHeroes Where will I find this sudhanshu property or a function?

  1. In the arrays prototype

  2. In the arrays prototype's prototype

2, yes Absolutely correct, and that is exactly happening.

But since we studied in the object class we don't need to say something like myHeroes.prototype.prototype.sudhanshu(), I can directly access all these prototypes this is what we established in the object class.

And if I had to thoroughly summarize this is exactly a prototypal chaining that you keep on chaining onto your prototypes and that's your prototypal chaining, this is a kind of inheritance also, and exactly this is prototypal inheritance also.

Now let's do some interesting stuff, We need to define actually some of the objects that are actually required for our next example

const User = {
    name: 'top name',
    email: 'topuser@gmail.com'
}
const Teacher = {
    makeVideos: true
}
const TeachingSupport = {
    isAvailable: false
}
const TSAssistant = {
    makeAssignment: 'JS assignment',
    fullTime: true
}

Now comes the interesting part I have access to these, now Here is the goal that I want to achieve, Let's just say this TeachingSupport is a big gigantic object maybe you are taking values from some payment gateways or maybe you have installed some npm package or something like that

So I want whatever properties are there in the TeachingSupport There could be hundreds of properties, these properties should be available to me in TSAssistant Also, that is my goal, listen to this question very carefully

There is a TeachingSupport which is an object may be coming from an API request or something like that You want that all of its properties should be available to you directly in the TSAssistant but it should not pollute your object as well, just like we studied in the object

So the one way is to dump all these properties into its prototype how can I do this, this is really simple this is really an old way of doing things, I will show you the modern way of doing things but yes you will still find a lot of code actually using like this

old syntax

const User = {
    name: 'top name',
    email: 'topuser@gmail.com'
}
const Teacher = {
    makeVideos: true
}
const TeachingSupport = {
    isAvailable: false
}
// old way
const TSAssistant = {
    makeAssignment: 'JS assignment',
    fullTime: true,
    __proto__: TeachingSupport
}

This syntax is a little bit older but again a lot of people still use the old codebase so that's why you might see that

Now run this on the browser and see

There are two properties in TSAssistant which are makeAssignment and fullTime and if I open up its prototype we can see isAvailable is directly injected in its prototype, although it itself is an object I told you everything inherits from some of a global object that's where the properties are defined.

Okay, this is actually one of the ways how we actually do it you can actually do a little bit more for example we have this Teacher Let's see how the teacher can be bound with the user

So what you can do is you can still access although __proto__ is a declared property but I haven't declared __proto__ So I can go ahead and say

const User = {
    name: 'top name',
    email: 'topuser@gmail.com'
}
const Teacher = {
    makeVideos: true
}
const TeachingSupport = {
    isAvailable: false
}
const TSAssistant = {
    makeAssignment: 'JS assignment',
    fullTime: true,
    __proto__: TeachingSupport
}
Teacher.__proto__ = User

and now you will inherit properties from User

Now the big question is can I access Teacher.email After this line of code Teacher.__proto__ = User

yes you can access it

So these are the ways which you are going to see in the old code bases.

modern syntax

The modern syntax is to take this object and just like we all these options now we have option Object.setPrototypeOf() and all we have to do is define the object to change its prototype and from where you are going to be changing for example

const User = {
    name: 'top name',
    email: 'topuser@gmail.com'
}
const Teacher = {
    makeVideos: true
}
const TeachingSupport = {
    isAvailable: false
}
const TSAssistant = {
    makeAssignment: 'JS assignment',
    fullTime: true,
}
Object.setPrototypeOf(TeachingSupport, Teacher)

TeachingSupport will get some properties from Teacher as well

So whatever Teacher is doing TeachingSupport will also do, so the Teacher is making a video now TeachingSupport will also make videos

Our starting goal

We learned so many things but till now our main goal has not been achieved yet

Goal : get trueLength of string

How can we do this can you solve this challenge now?

let myName = "Sudhanshu   "
console.log(myName.length)

// output
12

Answer :

let myName = "Sudhanshu   "
String.prototype.trueLength = function(){
    return this.trim().length
}
console.log(myName.trueLength());

// output
9

Here I target String to inject trueLength but we can grab the value of the String with the help of this , we studied a lot about this in the object class.