Наследование прототипов JavaScript — правильный ли это способ?

Если я объявлю базовый объект-прототип вне конструктора объекта, все созданные объекты будут основаны на этом единственном базовом объекте, который не подходит для моих нужд, поскольку мне нужно более одного экземпляра базового объекта.

Вкратце: правильный ли этот код? Это работает, но я требователен к правильному коду.

Пример:

function BaseObject()
{
    BaseObject.prototype.insertObject = function()…
    …
    … // Some other functions.
}

function Object1()
{
    Object1.prototype = new BaseObject();

    Object1.prototype.coolFunction = function()…
    …
    … // Same kind of pattern.
}

function Object2()
{
    Object2.prototype = new Object1();

    Object2.prototype.incredibleFunction = function()…
    …
    … // You get the idea.
}

person user1092719    schedule 09.02.2012    source источник


Ответы (2)


Общий шаблон:

function Base ( baseMember ) {
    this.baseMember = baseMember;
}

Base.prototype.baseFunc = function () {};

function Derived ( baseMember, derivedMember ) {
    Base.apply( this, arguments );   
    this.derivedMember = derivedMember;
}

Derived.prototype = Object.create( Base.prototype );
Derived.prototype.constructor = Derived;

Derived.prototype.derivedFunc = function () {};

Это некрасиво, я знаю...

person Šime Vidas    schedule 09.02.2012

Нет, весь код, который сейчас находится внутри ваших функций-конструкторов, должен быть вне их. Прямо сейчас вы переназначаете эти свойства прототипа каждый раз, когда кто-то создает новый объект.

Наконец, полезные советы:

  • Вы всегда должны «исправлять» свойство constructor любых производных прототипов. Это особенность наследования JS; он перезаписывается. Люди редко полагаются на правильность свойства constructor, но иногда они это делают, и если вы этого не сделаете, то это будет выглядеть неправильно.
  • Object.create(Base.prototype) лучше, чем new Base(), если вы работаете в браузерах, которые его поддерживают, или используете es5-shim. Он только создает экземпляр объекта, а не создает его, что хорошо, поскольку вам не нужна фактическая копия объекта для выполнения прототипного наследования.

Все это будет выглядеть так:

function BaseObject() { }

BaseObject.prototype.insertObject = function () { };

function Object1() { }

Object1.prototype = Object.create(BaseObject.prototype);
Object1.prototype.constructor = Object1;
Object1.prototype.coolFunction = function () { };

function Object2() { }

Object2.prototype = Object.create(Object1.prototype);
Object2.prototype.constructor = Object2;
Object2.prototype.incredibleFunction = function () { };
person Domenic    schedule 09.02.2012
comment
Если я делаю Object1.prototype = new BaseObject(); вне конструктора, каждый объект, созданный из Object1, зависит от этого единственного экземпляра BaseObject. Мне нужен способ создания новых экземпляров BaseObject. - person user1092719; 09.02.2012
comment
Это все равно будет иметь место, даже если вы выполните это внутри конструктора. Object1.prototype совместно используется каждым экземпляром Object1, поэтому все, что вы делаете каждый раз, когда переназначаете его, — это заставляете каждый экземпляр Object1 полагаться на один и тот же вновь созданный прототип BaseObject. - person Domenic; 09.02.2012
comment
Но когда я делаю это в своем реальном коде, он работает так, как мне нужно, потому что каждый раз, когда вызывается конструктор, он устанавливает прототип объекта как вновь созданный экземпляр BaseObject, а затем я повторяю этот шаблон, и он работает нормально . Просто должен быть чистый и правильный способ сделать это. - person user1092719; 09.02.2012
comment
Это будет работать так, как вы это делаете; это просто неэффективно и нетрадиционно (неправильно). Также неверно задает прототип объекта the; он устанавливает прототип для каждого объекта. - person Domenic; 09.02.2012