Mastering JavaScript Prototypal Inheritance: Build Smarter, Reusable Code

Photo by Clark Tibbs on Unsplash

Mastering JavaScript Prototypal Inheritance: Build Smarter, Reusable Code

Unlock the Power of JavaScript Prototypal Inheritance for Efficient and Maintainable Code

What you are going to learn.

In this article, we'll dive deep into the concept of prototypal inheritance, exploring how it works, why it's so powerful, and how it can be used to create flexible and dynamic JavaScript applications.

Introduction of Prototypal Inheritance

In the world of JavaScript, objects are not just created; they learn. They learn from their parents (constructors), but they also learn from their grandparents (prototypes). This process is known as prototypal inheritance, and it's a fundamental concept that shapes how JavaScript objects behave and interact.

Let's say we have a basic blueprint for a user in a system, with certain properties (like name, email) and methods (like login, logout). Now, we want to create two special types of users: an admin and a guest. These new types of users should have all the abilities of a regular user, plus some additional or slightly different behaviors. Instead of rewriting or duplicating the code for those shared properties and methods, we want to extend the basic user blueprint, adding or tweaking only what's necessary for the admin and guest roles.

In other words, we’re not starting from scratch for each new user type. Instead, we’re building on top of the existing user structure, inheriting all its functionality and then customizing it as needed for admins and guests. This approach avoids redundancy and makes our code more efficient and easier to maintain.

// Basic User object with properties and methods
let user = {
  name: 'John Doe',
  email: 'john.d@yopmail.com',
  login() {
    console.log(`${this.name} has logged in.`);
  },
};

// Creating an Admin object by building on top of the User object
let admin = Object.create(user);
admin.name = 'Admin';
admin.role = 'admin';
admin.deleteUser = function(userName) {
    console.log(`${this.name} has deleted user ${userName}.`);
};

// Creating a Guest object by building on top of the User object
let guest = Object.create(user);
guest.name = 'Guest User';
guest.role = 'guest';
guest.login = function() {
    console.log(`${this.name} has logged in with limited access.`);
};

// Using the objects
admin.login(); // Admin User has logged in.
admin.deleteUser('John Doe'); // Admin User has deleted user John Doe.

Explanation:

  • user object: This is the base object with common properties and methods like name, email, and login.

  • admin object: Created using Object.create(user), which sets up the admin object to inherit everything from user. Then, we add or override specific properties and methods, such as adding the deleteUser method.

  • guest object: Also created using Object.create(user), inheriting from user. We override the login method to reflect the limited access a guest might have.

This approach allows us to reuse and extend the user object's functionality without duplicating code.

Object.create

  • Prototype inheritance can be easily done using the Object.create method, which is used to create a new object by using the existing object.

  • The new object just inherits the prototype of the given object.

Object.create(object, { newObjectproperties });

Object.prototype.constructor

  • Constructor is a method, present in every object in the Object [[prototype]].

  • Every object has a default constructor and constructors can also be assigned to values

hasOwnProperty

  • This method is used to check whether a property is present in the given object.

  • Let's consider an example,

      let amenities = {
        "title" : "Swimming Pool",
      };
      console.log(company.hasOwnProperty("title")); /// OUTPUT: true
    

Conclusion

  • Prototype inheritance in JavaScript is performed using the prototype property present in every object.

  • Performing prototype inheritance offers the main advantage of enabling methods in a class to be accessible to other classes.

  • You can utilize the __proto__ property or the Object.create() method to achieve prototype inheritance.

Thank You!

Thank you for reading!
I hope you enjoyed this post. If you did, please share it with your network and stay tuned for more insights on software development. I'd love to connect with you on LinkedIn or have you follow my journey on HashNode for regular updates.

Happy Coding!
Darshit Anjaria