Inheritance Between "Classes" - Object.create
Let's finally look at how we can use Object.create
in other to implement a complex prototype chain similar to what we implemented before with classes and constructor functions.
Below is the object we will use as our prototype to create a new Employee
object.
// This is going to be our parent class
const EmployeeProto = {
calculateAge() {
console.log(2022 - this.dateOfBirth);
},
// You can use any name
build(name, dateOfBirth, department) {
this.name = name;
this.dateOfBirth = dateOfBirth;
this.department = department;
},
};
const kevin = Object.create(EmployeeProto);
We already know that Object.create
is easier to use and understand. Hence, it shouldn't be too hard to implement a similar hierarchy between an Engineer
and an Employee
.
The EmployeeProto
object is the prototype of all EMployee
objects. But now, we want to add another prototype in the middle of the prototype chain. That is, between EmployeeProto
and the object.
So, what we are going to do is to make Engineer
inherit directly from Employee
const EngineerProto = Object.create(EmployeeProto);
const sarah = Object.create(EngineerProto);
With this, the EngineerProto
we just created is now the prototype of the sarah
object. And the EmployeeProto
is the prototype of the EngineerProto
object. Hence, EmployeeProto
is the parent prototype of sarah
, which means it's in its prototype chain.
Yeah, I know it might sound confusing 🫤. Below is a diagram that I hope will help you understand better.
With the scope chain correctly established, let's also add a build
method to the EngineerProto
object.
EngineerProto.build = function (name, dateOfBirth, department, position) {
EmployeeProto.build.call(this, name, dateOfBirth, department);
this.position = position;
};
Now, we can use the build
method to create a new Engineer
object.
sarah.build('Sarah Young', 1990, 'Engineering', 'Software Engineer');
console.log(sarah);
We can also add the present
method as we did before.
EngineerProto.present = function () {
console.log(
`Hello, my name is ${this.name}, and I am a ${this.position} in the ${this.department} department.`
);
};
And now we can use it to present sarah
.
sarah.present();
// Hello, my name is Sarah Young, and I am a Software Engineer in the Engineering department.
As you would expect, we should also be able to use the calculateAge
method on sarah
.
sarah.calculateAge(); // 32
Below is our well-structured prototype chain.
To finish, using this version, we can see that we don't worry about constructors, prototype properties, and the new
operator. It's just objects linked to other objects. And in my opinion, it's really simple to understand and really beautiful.