21
Prototype, Classes and More
Prototype is an important part of JavaScript, it gives objects the ability to inherit properties and methods from other objects. Classes makes inheritance easier as it provides an easier syntax.
Let's look into it...
So, where is the prototype, the prototype can be found on the properties on any object.
if you console.log()
the following example, we can see that the prototype is a property:
const myObj = {
x: 100,
y: 200,
}
console.log(myObj);
The prototype is there as another property for the object we just created __proto__: Object
, but as shown on the example above there is a value being exposed on the __proto__
, this is the Object.prototype
. But how did that get in there, If you check inside the object we can see other properties and methods that have been inherited by default from the Object.prototype
. This is called the prototype chain.
Each object has a property called __proto__
which is the link to another object as their prototype. This property inherits all the properties and methods from the object that has been used in the prototype. Let's follow up on the example above.
Here there we will create another object with Object.create()
which creates an object and sets the prototype to the object passed as argument. Then set a property of z
to 50
in the newly created object.
const myObj = {
x: 100,
y: 200,
}
const anotherObj = Object.create(myObj);
anotherObj.z = 50;
console.log(anotherObj);
Once the object is created the prototype chain will be set. by expanding the property __proto__
on the developer tools it's evident that it has correctly inherited the x
and y
properties from the other object. See Image Below.
In the prototype chain it's visible that the other object still inherits from the Object.prototype
.
This happens because Object.protoype
will always be at the top of the prototype inheritance chain, this means that the __proto__
for Object.prototype
is null
.
The way the object was created with Object.create()
was by using other object as a prototype but there are other ways to create a inherit the prototype of an object.
Now that we have a better understanding of what the prototype, let's see the two approaches that we have to creating objects and prototype inheritance in ES5 and ES6.
We can either use constructor functions or the constructor method in classes to create objects. In order to create the object instance we have to use the new
keyword.
// ES5
function MyObj() {
this.x = 100;
this.y = 200
}
const obj1 = new MyObj();
console.log(obj1)
// ES6
class MyObj {
constructor() {
this.x = 100;
this.y = 200
}
}
const c1 = new MyObj();
console.log(c1);
both of the examples above yield the same results except that the constructor for the newly created objects points to either the constructor function
or the constructor()
method in the class
Now let's see the steps to inherit properties and methods in another object by using constructor functions, the ES5 way.
- Create the parent constructor function.
function MyObj(x, y) {
this.x = x;
this.y = y;
}
- Add Desired Methods to the constructor function prototype.
MyObj.prototype.sum = function() {
return this.x + this.y;
}
- Create the child constructor function and execute the parent constructor inside the child constructor by using
MyObj.call(this, x, y)
function AnotherObj(x,y,z) {
MyObj.call(this, x, y);
this.z = z;
}
Another way to execute the parent constructor inside the child constructor is the following. but this will only work because later on we will be calling the child constructor.
function AnotherObj(x,y,z) {
Object.getPrototypeOf(AnotherObj.prototype).constructor.call(this, x ,y)
this.z = z;
}
- Set the child object prototype to the parent object in order inherit the methods that were added previously in the parent constructor function.
AnotherObj.prototype = Object.create(MyObj.prototype);
- Reset the child constructor to be itself.
AnotherObj.prototype.constructor = AnotherObj;
- Create a new instance of the child object.
const anotherObj1 = new AnotherObj(100, 200, 50);
When we console log the instance we get the following structure in the prototype chain. Which shows that we have inherited the properties and methods from the parent object.
console.log(anotherObj1);
We can do this more efficiently with ES6 classes.
- Create parent class with constructor and methods.
class MyObj {
constructor() {
this.x = 100;
this.y = 200
}
sum() {
return this.x + this.y;
}
}
- Create child class and execute the parent constructor by calling
super(x,y)
.
class AnotherObj extends MyObj {
constructor(x,y,z) {
super(x,y);
this.z = z;
}
}
- Create instance
const anotherObj1 = new AnotherObj(100, 200, 50);
Once we console log the newly created object we see the same results
console.log(anotherObj1)
The only difference is that the constructor is the class rather than the function constructor.
I hope it is useful as it was useful to me in order to gain deeper understanding in the topic. Thank you for reading. Share your feedback. and let me know if you feel something is not right. Happy Coding!
21