4.1 Inheritance is Easy
Inheritance is a fundamental concept in Object-Oriented Programming (OOP), which allows a class (called a child or subclass) to inherit fields and methods from another class (called a parent or superclass).
This approach lets you create more general classes and reuse code, improving code organization and maintainability.
Why use inheritance?
Let's say you need to write some code and decide to do it as a class. Then you find out there's already a class in your project that does almost everything you need. You could just copy the code into your class and enjoy.
Or you could "kind of copy." You can declare that class as the parent of your class, and then JavaScript will add the parent class's behavior to your class.
Imagine you're nature and want to create a Dog. What's faster: creating a dog from bacteria over a billion years or domesticating a wolf in 200,000?
4.2 Prototype Inheritance Concept
Prototype inheritance in JavaScript is one of the main mechanisms that allows objects to inherit properties and methods from other objects. This lets you create complex object hierarchies and reuse code.
Every object in JavaScript has a hidden [[Prototype]] property that points to its prototype. Prototypes are used to implement inheritance, allowing objects to inherit properties and methods from other objects.
Simple Inheritance Example
Step 1: Create a Base Object
const animal = {
eat() {
console.log('Eating...');
},
sleep() {
console.log('Sleeping...');
}
};
Step 2: Create a Child Object
const dog = Object.create(animal);
dog.bark = function() {
console.log('Barking...');
};
Step 3: Use Inherited Properties and Methods
dog.eat(); // Outputs: Eating...
dog.sleep(); // Outputs: Sleeping...
dog.bark(); // Outputs: Barking...
In this example, the dog
object inherits the eat()
and sleep()
methods from the animal
object and adds its method — bark()
.
4.3 Deep Prototype Inheritance
Prototype Chain
In JavaScript, inheritance can be more complex when objects inherit from each other, forming a prototype chain.
Prototype Chain Example
In this example, the dog
object inherits from mammal
, which in turn inherits from animal
. This creates a prototype chain allowing dog
to access all methods of mammal
and animal
.
const animal = {
eat() {
console.log('Eating...');
}
};
const mammal = Object.create(animal);
mammal.walk = function() {
console.log('Walking...');
};
const dog = Object.create(mammal);
dog.bark = function() {
console.log('Barking...');
};
dog.eat(); // Outputs: Eating...
dog.walk(); // Outputs: Walking...
dog.bark(); // Outputs: Barking...
Checking the Prototype Chain
The isPrototypeOf()
method lets you check if an object is a prototype of another object.
Example:
console.log(animal.isPrototypeOf(mammal)); // Outputs: true
console.log(mammal.isPrototypeOf(dog)); // Outputs: true
console.log(animal.isPrototypeOf(dog)); // Outputs: true
4.4 Overriding Methods
Prototype inheritance lets you not only add new methods but also override existing ones.
Method Overriding Example
In this example, the speak()
method of the dog
object overrides the speak()
method of the animal
object:
const animal = {
speak() {
console.log('Animal speaks');
}
};
const dog = Object.create(animal);
dog.speak = function() {
console.log('Dog barks');
};
animal.speak(); // Outputs: Animal speaks
dog.speak(); // Outputs: Dog barks
Calling a Parent Object's Method
To call a parent object's method in JavaScript, you can use the call()
or apply()
method.
Example:
const animal = {
speak() {
console.log('Animal speaks');
}
};
const dog = Object.create(animal);
dog.speak = function() {
animal.speak.call(this);
console.log('Dog barks');
};
dog.speak();
// Outputs:
// Animal speaks
// Dog barks
4.5 Advanced Usage of Prototype Inheritance
Extending Built-in Objects
You can extend JavaScript's built-in objects by adding methods to their prototypes.
Example:
Array.prototype.sum = function() {
return this.reduce((acc, value) => acc + value, 0);
};
const numbers = [1, 2, 3, 4, 5];
console.log(numbers.sum()); // Outputs: 15
Creating Multi-Level Hierarchies
You can create more complex multi-level object hierarchies using prototype inheritance.
Example:
const livingBeing = {
breathe() {
console.log('Breathing...');
}
};
const animal = Object.create(livingBeing);
animal.eat = function() {
console.log('Eating...');
};
const mammal = Object.create(animal);
mammal.walk = function() {
console.log('Walking...');
};
const dog = Object.create(mammal);
dog.bark = function() {
console.log('Barking...');
};
dog.breathe(); // Outputs: Breathing...
dog.eat(); // Outputs: Eating...
dog.walk(); // Outputs: Walking...
dog.bark(); // Outputs: Barking...
GO TO FULL VERSION