Наследование в JavaScript

Как известно, методы «класса» в JavaScript лучше всего определять на прототипе, а свойства — на конструкторе, потому что методы нежелательно дублировать, определяя заново в каждом объекте, а значения свойств должны быть уникальны для каждого объекта.

Как же реализовать наследование?

Концепция наследования через цепь прототипов

Можно реализовать наследование через цепочку прототипов. Объявляются два «класса», прототип «потомка» объявляется как новый объект, созданный вызовом конструктора «родителя». Вот так:

function SuperType(){
}

function SubType(){
}

SubType.prototype = new SuperType();

Такой подход создаёт только две проблемы:

1. Ссылочные значения делятся между всеми «потомками» «родителя».

2. Нельзя передать аргументы конструктору «родителя».

Способ, предложенный в книге JavaScript Allongé:

Берем суперкласс Superclass, объявляем для него пустой прокси-класс:

var SuperclassProxy = function () {
    this.constructor = Subclass;
}
SuperclassProxy.prototype = Superclass.prototype

Далее мы используем конструктор прототипа суперкласса в конструкторе класса-потомка. В качестве прототипа класса-потомка используем конструктор прокси-класса. Сам прокси-класс нужен, чтобы случайно не испортить что-нибудь в суперклассе при вызове его конструктора. Например, если в конструкторе выполняется подключение к БД, то не выполнять его при каждом наследовании.

var Subclass = function () {
    Superclass.prototype.constructor.call(this)
};

Subclass.prototype = new SuperclassProxy();

Далее мы делаем копию объекта (shallow copy) Superclass и дополняем ее методами и свойствами Subclass.

Решение, предложенное в книге Effective JavaScript:

Допустим, у нас есть SuperType, и мы пытаемся создать SubType на его основе.

function SubType(arg1, arg2, arg3) {
     SuperType.call ( this, arg1, arg2, arg3);
     // разные действия в собственно конструкторе SubType
}
SubType.prototype = Object.create(SuperType.prototype); // наследуем прототип

Здесь мы сначала вызываем конструктор SuperType, передавая туда все требуемые аргументы, а в качестве приёмника будет SubType.

Затем наследуем прототип SuperType.

 

Оставить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.