Наследование в js можно разделить на два типа: олицетворение объекта и цепочка прототипов.
1. Олицетворение объекта включает три типа : метод временного атрибута, метод call() и метод apply().
1. Метод временного атрибута
Скопируйте код кода следующим образом:
функция Человек(имя){
это.имя = имя;
this.say = функция(){
alert('Меня зовут '+this.name);
}
}
функция F2E(имя,идентификатор){
this.temp = Человек;
this.temp(имя);
удалить этот.temp;
this.id = идентификатор;
this.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
}
вар Саймон = новый F2E('Саймон',9527);
Саймон.Сай();
Саймон.showId();
2. метод call()/apply()
По сути, он меняет указатель этого указателя.
Скопируйте код кода следующим образом:
функция Человек(имя){
это.имя = имя;
this.say = функция(){
alert('Меня зовут '+this.name);
}
}
функция F2E(имя,идентификатор){
Person.call(this,name); //метод apply() изменен на Person.apply(this,new Array(name));
this.id = идентификатор;
this.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
}
вар Саймон = новый F2E('Саймон',9527);
Саймон.Сай();
Саймон.showId();
Недостатки: Давайте сначала посмотрим на эту диаграмму распределения памяти:
В концепции ОО после создания экземпляра new объект формирует собственное пространство в куче памяти. Стоит отметить, что этот сегмент кода. В этом сегменте кода существуют методы-члены, и эти методы являются общими. Проблема вот в чем: при наследовании через олицетворение объекта все методы-члены указывают на это. То есть после создания каждый экземпляр будет иметь этот метод-член, который не является общим, что приводит к большим потерям памяти. А из-за олицетворения объекта переменные и методы, определенные через прототип, не могут быть унаследованы. Например, следующий код вызовет ошибку:
Скопируйте код кода следующим образом:
функция Человек(имя){
это.имя = имя;
this.say = функция(){
alert('Меня зовут '+this.name);
}
}
Person.prototype.age = 20;
Person.prototype.sayAge = function(){alert('Мой возраст '+this.age)};
функция F2E(имя,идентификатор){
Person.apply(this,new Array(name));
this.id = идентификатор;
this.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
}
вар Саймон = новый F2E('Саймон',9527);
simon.sayAge(); //Ошибка типа запроса: simon.sayAge не является функцией
2. Метод цепочки прототипов
Скопируйте код кода следующим образом:
функция Человек(){
this.name = 'Саймон';
}
Person.prototype.say = функция(){
alert('Меня зовут '+this.name);
}
функция F2E(id){
this.id = идентификатор;
this.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
}
F2E.prototype = новый человек();
вар Саймон = новый F2E (9527);
Саймон.Сай();
Саймон.showId();
alert(simon.hasOwnProperty('id')); //Проверяем, является ли это собственным свойством
Затем следуйте приведенному выше примеру, чтобы понять следующие концепции цепочки прототипов js:
Цепочку прототипов можно понимать так: каждый объект в js имеет скрытый атрибут __proto__. Атрибут __proto__ экземпляра объекта указывает на метод прототипа его класса, и этот метод прототипа может быть назначен другому экземпляру объекта, __proto__. этот объект должен указывать на свой класс, образуя таким образом цепочку, которая является
Скопируйте код кода следующим образом:
F2E.prototype = новый человек()
Это предложение является ключевым. Когда объект js считывает определенный атрибут, он сначала ищет свои собственные атрибуты. Если атрибутов нет, он затем ищет атрибуты объекта в цепочке прототипов. Другими словами, методы цепочки прототипов могут быть общими, что решает проблему олицетворения объекта и бесполезной траты памяти.
Теперь поговорим о недостатках:
Недостаток цепочки наследования прототипов означает, что параметры не могут быть переданы родительскому классу при создании экземпляра подкласса. Вот почему функция Person() в этом примере не имеет параметров и напрямую записывается как this.name="Simon". Следующий код не даст желаемого эффекта:
Скопируйте код кода следующим образом:
функция Человек(имя){
это.имя = имя;
}
Person.prototype.say = функция(){
alert('Меня зовут '+this.name);
}
функция F2E(имя,идентификатор){
this.id = идентификатор;
this.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
}
F2E.prototype = новый человек();
вар Саймон = новый F2E («Саймон», 9527);
Саймон.Сай();
Саймон.showId();
функция Человек(имя){
это.имя = имя;
}
Person.prototype.say = функция(){
alert('Меня зовут '+this.name);
}
функция F2E(имя,идентификатор){
this.id = идентификатор;
this.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
}
F2E.prototype = new Person(); // Здесь нельзя передать значение, ни this.name, ни name не подойдут. Можно напрямую написать F2E.prototype = new Person('wood'), но в этом случае simon. Say( ) становится Меня зовут Вуд
вар Саймон = новый F2E («Саймон», 9527);
simon.say(); //Всплывающее окно Мое имя не определено
Саймон.showId();
Наконец, позвольте мне суммировать то, что я считаю лучшим способом реализации наследования. Переменные-члены используют олицетворение объекта, а методы-члены используют цепочку прототипов. Код выглядит следующим образом:
Скопируйте код кода следующим образом:
функция Человек(имя){
это.имя = имя;
}
Person.prototype.say = функция(){
alert('Меня зовут '+this.name);
}
функция F2E(имя,идентификатор){
Person.call(это,имя);
this.id = идентификатор;
}
F2E.prototype = новый человек();
//Обратите внимание на одну деталь: showId нельзя писать перед F2E.prototype = new Person();
F2E.prototype.showId = функция(){
alert('Доброе утро, сэр, мой рабочий номер: +this.id);
}
вар Саймон = новый F2E («Саймон», 9527);
Саймон.Сай();
Саймон.showId();