Наследование в javascript
Шаблон №1
jQuery
// родительский конструктор
function Parent(name){
this.name = name || 'Вася';
}
// добавляем в прототип род. конструктора метод getName
Parent.prototype.getName = function(){
return this.name;
}
// дочерний конструктор
function Child(name){ };
// наследование
function inherit(C,P){
C.prototype = new P();
// важно отметить, что здесь ссылка на объект(экземпляр) конструктора,
// а не на сам конструктор
}
inherit(Child, Parent);
var people = new Child();
people.getName(); // Вася
// Недостаток
var peopleTwo = new Child('Петя');
peopleTwo.getName(); // Вася
Недостатки: дочерние объекты наследуют не только свойства прототипа родительского объекта, но и свойства, добавленные к самому объекту.
При использовании функции inherit()
, невозможно передать параметры, полученные дочерним конструктором, от дочернего конструктора родительскому.
Шаблон №2
Следующий шаблон решает передачу аргументов от дочернего конструктора родительскому конструктору.
Однако свойства, добавленные в прототип, не наследуются.
Наследуются только свойства от конструктора-родителя; свойства от прототипа не наследуются.
Дочерние объекты получают копии унаследованных членов (в 1 примере получают ссылки)
Шаблон №2 для первого примера
jQuery
// родительский конструктор
function Parent(name){
this.name = name || 'Вася';
}
// добавляем в прототип род. конструктора метод getName
Parent.prototype.getName = function(){
return this.name;
}
// дочерний конструктор
function Child(name){
Parent.apply(this, arguments);
};
var peopleTwo = new Child('Петя');
peopleTwo.name; // Петя
typeof peopleTwo.getName; // "undefined"
Недостатки: так как здесь не используется свойство Child.prototype
(оно ссылаеся на пустой объект),
то не наследуются свойства прототипа.
javascript
function Sport(){
this.sort = ['Hockey','Soccer'];
}
var sport = new Sport();
function ShowSport() {};
ShowSport.prototype = sport;
// объект наследует свойства объекта sport
// посредством класс-го наблона №1
var blogSport = new ShowSport();
// объект от нижеприведенного конструктора наследует свойства
// объекта sport через шаблон заимствования конструктора
function CurrentSport() {
Sport.call(this);
}
var tvSport = new CurrentSport();
console.log(sport.hasOwnProperty('sort')); // true
console.log(blogSport.hasOwnProperty('sort')); // false
console.log(tvSport.hasOwnProperty('sort')); // true
blogSport.sort.push('Baseball');
tvSport.sort.push('Basket');
console.log(sport.sort.join(', ')); // Hockey, Soccer, Baseball
// как видите, изменение значение свойства tvSport.sort не приведет
// к изменению в родительском объекте sport
// (так как tvSport.sort является отдельной копией)
Шаблон №3
Объединяет преимущества двух предыдущих шаблонов. Дочерний объект получает КОПИИ собственных членов родительского объекта и ССЫЛКУ на функциональные возможности род-го объекта (члены прототипа).
- Заимствуем конструктор
- В совйстве ptototype дочернего объекта сохраняем ссылку на новый экземпляр конструктора
jQuery
// родительский конструктор
function Parent(name){
this.name = name || 'Вася';
}
// добавляем в прототип род. конструктора метод getName
Parent.prototype.getName = function(){
return this.name;
}
// дочерний конструктор
function Child(name){
Parent.apply(this, arguments);
};
Child.prototype = new Parent();
var peopleTwo = new Child('Петя');
//peopleTwo.name; // Петя
//peopleTwo.getName(); // Петя
delete peopleTwo.name;
peopleTwo.getName(); // Вася
Недостатки: приходится дважды вызывать родительский конструктор,
поэтому собственные свойства, например, name
наследуются дважды.
Комментарии к статье