Итак, мы настроили цепочку наследования как следует.

function Shape(color) {
    this.color = color;
}

Shape.prototype.duplicate = function () {
    console.log('duplicate');
}

function Circle(radius, color) {
    Shape.call(this, color);
    this.radius = radius;
}

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

Circle.prototype.draw = function () {
    console.log('draw');
}

Circle.prototype.smoke = function () {
    console.log('smoke');
}

const s = new Shape();
const c = new Circle(1, 'red');

Теперь давайте создадим другой объект, например square, который унаследуется от shape.

Итак мы создадим конструктор Square, который принимает size

function Suare(size) {
    this.size = size;
}

Теперь мы хотим чтобы он наследовался от Shape.
Пропишем следующие строки, для переопределения прототипа.

Square.prototype = Object.create(Shape.prototype);
Square.prototype.constructor = Square;

Однако, эти две строчки кода для установки нашей цепочки прототипов мелькают уже слишком часто. И чем больше мы будет создавать конструкторов, тем проще будет допустить ошибку.

Поэтому, хорошим подспорьем будет вынести этот кусок кода в функцию, которую мы можем переиспользовать.

Создадим функцию extend, которая будет получать два параметра — child и parent.

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