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?
In the arrays prototype
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.