Calling Super Constructor

В дополнению к этому коду, изменим конструктор Shape и внесем параметр color. Мы хотим чтобы каждый shape имел цвет.

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

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

function Circle(radius) {
    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);

В текущей реализации, когда мы создаем circle, мы передаем только radius.
Если мы посмотрим на объект в переменной c, то мы увидим только свойтсов radius. Здесь нет никакого color.

Но с точки зрения наследования, этот circle объект должен иметь свойство color и оно должно быть инициализировано в момент создания объекта circle.

Что нам для этого потребуется?

В конструкторе Circle, нам нужно вызвать конструктор Shape.

Сначала посмотрим на неправильный способ.

function Circle(radius, color) {
    Shape(color);
    this.radius = radius;
}
//...
const c = new Circle(1, 'red');

Если мы посмотрим на объект в переменной c — мы увидим что в нём нету свойства color.

Почему же так получилось?
Ранее мы обсуждали, что когда мы используем оператор new — происходит три вещи. Этот new оператор создает новый пустой объект, затем устанавливает this в контекст этого объекта. То есть мы устанавливаем свойство this.radius этому новому объекту. И наконец, этот новый объект будет возвращен из конструктора Circle.

Еще мы говорили о том, что если не использовать этот оператор newthis по умолчанию будет указывать на глобальный объект, который является window в браузере и global в ноде. Итак, причина, почему не работает — мы вызываем функцию Shape, и по умолчанию this, которая находится в ней будет указывать на глобальный объект. Т.е. мы не установим свойство color на новый экземпляр объекта circle. Мы установим его глобальному объекту.

И как нам решить эту проблему?

Мы не хотим использовать оператор new при вызове функции-конструктора Shape в конструкторе Circle, т.к. будет создан другой новый объект. И свойство color установится этому объекту. Мы хотим, использовать объект, на который ссылается this. Чтобы исправить эту проблему, нам нужно вызвать Shape функцию, и указать this как контекст нового экземпляра объекта circle.

Ранее мы говорили, что каждая функция в JavaScript является объектом. И у них есть свойства и методы. Так вот мы также говорили про метод call. И мы можем вызвать эту Shape функцию в контексте экземпляра объекта Circle. Т.е. в качестве контекста укажем this, остальными параметрами являются аргументы.

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