Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > JavaScript: Общие вопросы > вызов конструктора прототипа


Автор: rene 1.8.2007, 09:50
Задача: обеспечить вызов сначала  метода-конструктора унаследованного объекта-конструктора,
а затем собственного метода-конструктора. В случае, если объект-конструктор не наследует
другой объект-конструктор не пытаться вызывать коструктор  прототипа.

Есть два объекта-конструктора А и B. Каждый из них содержит в себе публичный метод "construct",
который вызывается при создании экземпляра объекта-конструктора с параметром "id",
то есть:

Код

b = new B(123)

приведёт к тому, что при создании "b" вызовется метод конструктора "construct".

А если унаследовать "А"
Код

B.prototype = new A()

, то 
нужно вызвать метод-конструктор "А", а зетем свой собственный
метод-конструктор.

Сделал вот так, но работает только в Мозилле, так как в ней есть свойство "constructor.name":

Код

function A(id)
{
    this.construct = function(id)
    {
        alert("Called A.constructor")
    }
    if(id)
        this.construct(id)
}

function B(id)
{
    this.name = "B"
    this.construct = function(id)
    {
        if (this.constructor.name != this.name)
            this.constructor(id)
        alert("Called B.constructor")
    }
    if(id)
    {
            this.construct(id)
    }
}

B.prototype = new A()
var b = new B(1)


Как быть?



Автор: rene 1.8.2007, 10:09
Вот так работает всюду, но как-то неизящно:

Код

function A(id)
{
    this.selfName = "A"
    this.construct = function(id)
    {
        alert("Called A.constructor")
    }
    if(id)
        this.construct(id)
}

function B(id)
{
    this.construct = function(id)
    {
        if (this.selfName == "A")
            this.constructor(id)
        alert("Called B.constructor")
    }
    if(id)
    {
            this.construct(id)
    }
}

B.prototype = new A()
var b = new B(1)


Автор: Zeroglif 1.8.2007, 11:25
rene, 

внутри функции B вызвать:

Код

    B.prototype.construct();
    this.construct();

первую строчку естесственно вызывать при наличии таковой функции в прототипе (с проверкой), иначе только вторую. Если же идея в том, чтобы привязаться к this, то сразу же при входе в функцию B (ещё до заведения собственных слотов):

Код

if (this.construct) this.construct();

а потом уже завести собственный construct и вызвать. Или я не понял затею?

Автор: rene 1.8.2007, 12:52
конгениально smile
да, идея была сделать это через "this".
но оба решения мне нравятся. спасибо.
>ещё до заведения собственных слотов
ага,  значит потом метод перезапишется собствененным методом "construct" B?

Автор: Zeroglif 1.8.2007, 13:17
Цитата(rene @  1.8.2007,  12:52 Найти цитируемый пост)
значит потом метод перезапишется собствененным методом

Скорее не перезапишется, а затенит/закроет наследуемый метод с тем же именем. Сначала, ввиду отсутствия явно заданного слота, объект b не может обработать сообщение и делегирует его своему прототипу (тому который создан через new A). Потом вы заводите явный слот, в следующий раз сообщение будет обработано уже самим получателем.

А в вашем последнем примере беда в том, что, вызывая this.constructor() вы перезаписываете (именно перезаписываете) собственные слоты объекта b, потому что он передаётся в A контекстной переменной. В результате одна и та же функция будет жить и в объекте и в его прототипе, проверим:

Код

b.construct();     //-> Called A.constructor (собственный слот)
delete b.construct 
b.construct();     //-> Called A.constructor (наследуемый слот)

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)