JavaScript

Last Updated: 2/2/2023

Custom Inheritance

  • Use Object.create to set the inheritance
  • Set the constructor property after chaning the prototype
function Shape() {
}
Shape.prototype.paint = function() {
    console.log("paint");
}

function Circle(radius) {
    this.radius = radius;
}
Circle.prototype.draw = function() {
    console.log("draw");
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Cirlce;

Passing Parent Constructor Parameters

  • In the child constructor call the parent constructor
function Shape(color) {
    this.color = color;
}
Shape.prototype.paint = function() {
    console.log("paint");
}

function Circle(radius, color) {
    Shape.call(this, color); //calling parent constructor
    this.radius = radius;
}
Circle.prototype.draw = function() {
    console.log("draw");
}

// Set the prootype
Circle.prototype = Object.create(Shape.prototype);

// Set the constructor
Circle.prototype.constructor = Circle;

const circle1 = new Circle(10, "yellow");

Intermediate Function Inheritance

function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Parent;
}

extend(Circle, Shape);

Method Overriding

function extend(Child, Parent) {
    Child.prototype = Object.create(Parent.prototype);
    Child.prototype.constructor = Parent;
}

function Shape() {
}
Shape.prototype.paint = function() {
    console.log("paint");
}

function Circle() {
}

extend(Circle, Shape);

Circle.prototype.paint = function() {
    Shape.prototype.paint();
    console.log("circle paint");
}

const c1 = new Circle();

Polymorphism

  • Many forms of a method
function Square() {
}

extend(Square, Shape);

Square.prototype.paint = function() {
    Shape.prototype.paint();
    console.log("square paint");
}

const shapes = [
    new Circle(),
    new Square()
];
for(let shape of shapes)
    shape.paint();

Points to Remember

  • Inheritance is a great tool for solving the problem of code reuse, you have to be really careful about using it, because it can make your source code complex and fragile. If you have more types, hierarchy would get more and more complex
  • Start with simple objects, and then if you see a number of these objects share similar features, then perhaps you can encapsulate those features inside of a generic object, and use inheritance.
  • Composition can also be used for code reuse

Problem with Inheritance

Let say you have Animal object with two methods eat and walk. Then you have two objects that derive from animal. Person and Dog. If tomorrow you're going to introduce a new object called Goldfish that derives from animal your hierarchy is broken, because Goldfish cannot walk, they can only swim.

To solve this problem, you need to change your hierarchy. On the top you should have, the Animal object with the eat method. Under that you're going to have two objects, Mammal and Fish. Mammals can walk, Fish can swim and then you can have Person and Dog derive from Mammal and Goldfish derive from Fish.

As a result of introducing a new kind of animal, that is goldfish, you had to change your hierarchy, and now this hierarchy is more complex than before. What happens if you had ten different types of animals? This hierarchy would get more and more complex, and you have to constantly go back and forth, to determine the right place to implement a method, so, avoid creating inheritance hierarchies because they are very fragile.