Javascript-форум (https://javascript.ru/forum/)
-   Учебные материалы (https://javascript.ru/forum/study/)
-   -   Наследование на основе прототипов (https://javascript.ru/forum/study/52161-nasledovanie-na-osnove-prototipov.html)

wondertalik 06.12.2014 14:32

Наследование на основе прототипов
 
function Parent() {
    this.a = [];
}
Parent.prototype.dd = function() {
    console.log('f parent');
};
var aa =  new Parent();

function ChildB() {

}
ChildB.prototype = aa;

ChildB.prototype.dd = function() {
    console.log('b child');
};

function ChildC() {

}
ChildC.prototype = aa;

ChildC.prototype.dd = function() {
    console.log('c child');
};

new ChildB().dd();
new ChildC().dd();

Читая статью о наследовании на основе прототипов я похоже что-то упустил. Подскажите что именно.
Ожидалось что в консоле я увижу
b child
c child

А в итоге я получил:
c child
c child

danik.js 06.12.2014 14:39

Цитата:

Сообщение от wondertalik
childB.prototype.dd =

Это равнозначно aa.dd =, потому как:
Цитата:

Сообщение от wondertalik
childB.prototype = aa;

Таким образом, ты два раза записываешь aa.dd

У тебя оба child'а в качестве прототипа имеют один и тот же объект. Ты просто перетираешь его свойства.


Имена конструкторов принято записывать с большой буквы.

wondertalik 06.12.2014 14:50

childB.prototype = new parent();

childC.prototype =  new parent();
;

Подумал и подправил. Это правильное решение?

danik.js 06.12.2014 15:03

Цитата:

Сообщение от wondertalik
Это правильное решение?

Я не знаю почему во всех учебниках предлагают такой вариант. Но он не совсем верный.

Корректней будет так:

ChildC.prototype =  Object.create(Parent.prototype);
// по идее еще нужно переопределить свойство constructor


Тогда в прототип не попадет свойство a = []. Оно там не нужно. Оно должно быть у каждого инстанса свое.
Делается так:
function ChildC() {
    Parent.call(this);
}

wondertalik 06.12.2014 15:14

Цитата:

Сообщение от danik.js (Сообщение 344955)
Я не знаю почему во всех учебниках предлагают такой вариант. Но он не совсем верный.

Корректней будет так:

ChildC.prototype =  Object.create(Parent.prototype);
// по идее еще нужно переопределить свойство constructor


Тогда в прототип не попадет свойство a = []. Оно там не нужно. Оно должно быть у каждого инстанса свое.
Делается так:
function ChildC() {
    Parent.call(this);
}

Написано что в ie8- нет поддержки Object.create(), и предлагается использовать вот это
function inherit(proto) {
    function F() {}
    F.prototype = proto;
    return new F;
}


Цитата:

Сообщение от danik.js (Сообщение 344955)

ChildC.prototype =  Object.create(Parent.prototype);
// по идее еще нужно переопределить свойство constructor


Тогда в прототип не попадет свойство a = []. Оно там не нужно. Оно должно быть у каждого инстанса свое.
Делается так:
function ChildC() {
    Parent.call(this);
}

А если мне нужно чтобы массив а был один для всех с определенными элементами. В потомках он меняться не должен, но обращение к нему обязательно. Как быть?

danik.js 06.12.2014 15:21

Цитата:

Сообщение от wondertalik
Написано что в ie8- нет поддержки Object.create(), и предлагается использовать вот это

Если это использовать, то только для IE8. Для нормальных браузеров - Object.create. Это облегчает отладку.
Цитата:

Сообщение от wondertalik
А если мне нужно чтобы массив а был один для всех с определенными элементами

Ну так ты его в прототип Parent'а и ложи.

wondertalik 06.12.2014 15:45

Цитата:

Сообщение от danik.js (Сообщение 344962)
Если это использовать, то только для IE8. Для нормальных браузеров - Object.create.

Проблема в том, что на терминальном софте используется только ie. Как можно сделать, чтобы если существует create в Object, то используем его иначе inherit?
ChildC.prototype =  Object.create(Parent.prototype);

При таком подходе получается наследование от Object. Я правильно понимаю?
Цитата:

Ну так ты его в прототип Parent'а и ложи.
В смысле объявлять в конструкторе Parent'a?

danik.js 06.12.2014 16:02

Цитата:

Сообщение от wondertalik
При таком подходе получается наследование от Object. Я правильно понимаю?

Нет. Создается объект, прототип которого - переданный аргумент.
Работает примерно как твой inherit.
Цитата:

Сообщение от wondertalik
Как можно сделать, чтобы если существует create в Object, то используем его иначе inherit?

if (!Object.create) {
    Object.create = function() { ... };
}

Цитата:

Сообщение от wondertalik
В смысле объявлять в конструкторе Parent'a?

В смысле объявлять в прототипе Parent'а.


Часовой пояс GMT +3, время: 01:17.