Inheritance is the Concept using which you can inherit properties and methods from one Class to another Class. The Class from which we will inherit properties or methods that is Called parent Class. Which Class inherit from Parent Class that is Called Child Class.
This relationship is Similar to Father and Son relationship. You must noticed in major Cases kid inherits properties depending upon his or her parents.
In below I am showing an example of Person and Teacher Classes. My Person Class is having First Name, Last Name, Age and Gender. As teacher as a person my teacher class inherits all the properties of my person class. Additionally I am adding Salary as a new property.
/*Constructor Class*/
function person(firstname, lastname, age, gender) {
this.name = { firstname, lastname };
this.age = age;
this.gender = gender;
};
<h2>Object.create() Method</h2>
The `Object.create()` method provides explicit control over prototype assignment during object creation. This static method creates a new object with its prototype set to the specified object, offering an alternative to constructor-based inheritance.
Normally what we do, The time we Create the Class we design the properties and methods. Think once if we required some additional methods or properties to an existing Class without disturbing the Class, in this scenario prototyping is useful. Look at the below example here I am adding a greeting method to my person Class using Prototyping.
/*Prototyping Person Class*/
person.prototype.greeting = function() {
alert('Hi! I\'m ' + this.name.firstname + '.');
};
Creating an Instance
Here I am Creating an instance for my Person Class and Calling the method greeting.
var personInstance = new person("Bikash", "Dash", 27, "M", 20000);
personInstance.greeting();
In the below Code I am Creating the teacher Class by inheriting all the properties from Person Class. As the number of arguments known to me, here I used Call to bind person class properties to teacher class.
/*Teacher Class inherits from Person Class*/
function Teacher(firstname, lastname, age, gender, salary) {
person.call(this, firstname, lastname, age, gender);
this.salary = salary;
}
<h2>Prototypal Inheritance: The Foundation</h2>
JavaScript employs a unique inheritance model known as prototypal inheritance. Unlike classical inheritance languages such as Java or C++, where classes serve as blueprints for objects, JavaScript uses prototype objects as the mechanism for inheritance. Every JavaScript object possesses an internal property called `[[Prototype]]`, which references another object. This prototype object may have its own prototype, creating a chain known as the prototype chain.
When accessing a property on an object, JavaScript first searches the object itself. If the property is not found, the search continues up the prototype chain until either the property is found or the chain ends. This mechanism enables property and method sharing across multiple objects without requiring explicit copying.
/*To assign Person prototype we have to Create Prototype for Teacher*/
Teacher.prototype = Object.create(person.prototype);
var newTeacher = new Teacher("Baby", "Roy", 26, "F", 30000);
alert(newTeacher.name["firstname"]);
alert(newTeacher.gender);
/*After Teacher.Prototype only this will work*/
newTeacher.greeting();
Here if we alert(Teacher.prototype.constructor); it will show Person Class Constructor. To display Teacher Class Constructor we have to execute the following line of Code.
Constructor Functions
Before ES6 introduced the class syntax, constructor functions served as the primary method for creating objects with shared functionality. A constructor function resembles a regular function but gets invoked with the `new` keyword, which creates a new object and sets its prototype.
Constructor functions attach methods to the prototype property, ensuring that all instances share the same method references rather than creating separate copies for each instance. This approach optimizes memory usage and maintains the prototype chain relationship between instances.
Teacher.prototype.constructor = Teacher;
ES6 Classes: Syntactic Sugar
ECMAScript 2015 introduced the `class` keyword, providing cleaner and more intuitive syntax for inheritance while maintaining the underlying prototypal mechanism. Classes in JavaScript offer a formal structure that resembles classical OOP languages, making the language more accessible to developers from other backgrounds.
Method Overriding and Super Calls
When a child class defines a method with the same name as a parent class method, it overrides the parent's implementation. The child class can access the overridden method using the `super` keyword, which references the parent class directly.
Common Pitfalls and Best Practices
Inheritance in JavaScript requires careful consideration to avoid common problems. Deep prototype chains can impact performance, so developers should limit inheritance depth to reasonable levels. Modifying shared prototype properties affects all objects inheriting from that prototype, which can introduce unexpected behavior.
Preferring composition over inheritance often leads to more flexible code. Composition involves combining smaller objects to create more complex behavior, rather than establishing rigid inheritance hierarchies. This approach reduces coupling and makes systems easier to modify over time.
Developers should also avoid modifying built-in object prototypes, as this practice can conflict with third-party code and future language implementations.
Conclusion
Inheritance remains a powerful tool in JavaScript development, enabling developers to build sophisticated applications through hierarchical relationships between objects. From prototype-based delegation to modern class syntax, JavaScript offers multiple pathways to implement inheritance effectively. By understanding the underlying mechanisms and following established best practices, developers can leverage inheritance to create maintainable, efficient, and scalable applications that stand the test of time.