предисловие
Поделитесь наиболее распространенными и подробными методами наследования в js для всех.Далее будут показаны и объяснены следующие параметры.Статья немного длинная, пожалуйста, прочитайте ее терпеливо😁, если есть какие-либо недоразумения, пожалуйста, оставьте сообщение и укажите на это
- причина
- Код
- Фундаментальный
- языковая реализация
- Преимущества сцены
- недостаток
Наследование
- Наследование цепочки прототипов
- Заимствование наследования шаблона конструктора
- наследование композиции
- прототипное наследование
- паразитарное наследование
- паразитарное сочетание
Наследование цепочки прототипов
Я считаю, что все знают о наследовании цепочки прототипов (концепция цепочки прототипов описана в ECMAScript, и цепочка прототипов используется в качестве основного метода реализации наследования), потому что наследование цепочки прототипов очень мощное, но и у него есть свои недостатки. к приведенным выше измерениям, давайте посмотрим, что, черт возьми, такое наследование цепочки прототипов
Реализация кода: (для завершения наследования цепочки прототипов требуется два конструктора)
// SuperType 构造函数称为超类
function SuperType (){
this.name='super';
this.friend=[];
this.property = true;
}
SuperType.prototype.getName=function(){
return this.name;
}
SuperType.prototype.getSuperValue = function(){
return this.property;
};
// SubType 构造函数称为子类
function SubType(name,age){
this.name=name;
this.age=age;
this.subproperty = false;
}
SubType.prototype=new SuperType();
SubType.prototype.constrcutor=SubType;
SubType.prototype.getAge=function(){
return this.age;
}
SubType.prototype.getSubValue = function (){
return this.subproperty;
};
var child = new SubType('shiny',12);
console.log(child.getName)//shiny
console.log(child.getAge())//12
Свойства сечения диаграммы
Фундаментальный
Поиск наследования с использованием цепочки прототипов с аналогичной областью действияязыковая реализация
Определите два конструктора, соответственно, родительский класс (Supertype), подкласс (подтип), может быть использован для достижения свойств подкласса (сам свойства и прототип выше) родительского класса. Переписать прототип подкласс, подкласс направлен, так что конструктор экземпляра Prototype родительского класса является экземпляром этого подкласса адреса родительского класса, подкласс может быть реализован с использованием свойства на сам родительский класс и самого прототипапреимущество
Подклассы могут выполнять поиск по цепочке прототипов, чтобы реализовать общедоступные свойства родительского класса и экземпляры подклассов.
недостаток
- Некоторые временные справочные операции данных будут проблемы, два экземпляра наследуют общую ссылку на классы данных экземпляра.
- Тщательное определение методов, чтобы не определять методы, которые также наследуют одно и то же имя методов от прототипа объекта.
- Невозможно использовать параметры непосредственно в родительском конструкторе
Заимствование наследования шаблона конструктора
Хотя наследование по цепочке прототипов очень эффективно, оно также имеет свои недостатки.Заимствование наследования конструктора может устранить недостатки наследования по цепочке прототипов.Код:
// 把父类当中一个函数使用
function SuperType(name){
this.name=name
this.friend=['a','b']
}
SuperType.prototype.getFriend=function(){
return this.firend
}
function SubType(name){
// 执行父类函数
SuperType.call(this,name);
}
var child = new SubType('shiny')
var childRed = new SubType('red')
console.log(child.name)//shiny
console.log(childRed.name)//red
child.firend.push('c')
console.log(child.friend)//a,b,c
console.log(childRed.friend)//a,b
console.log(childRed.getFriend)//undefined
Фундаментальный
Метод использования вызова применяется, изменяет tihs (контекст), выполняя метод, является родителем этого подкласса в этом экземпляре, так что каждый экземпляр будет предоставлять свойства родительского класса для достижения резервных эталонных свойствсцены, которые будут использоваться
Некоторым подклассам в родительском классе необходимо использовать общие ссылочные типы, и подклассы могут работать с ссылочными типами, общими для родительского класса. Но не связанные с этим свойства и методы родительского класса не могут быть использованы (свойства и методы прототипа родительского класса)языковая реализация
Ставьте не конструктор родительского класса, а одну из функций.Так проще понять.В конструкторе подкласса позаимствуйте функцию родительского класса для выполнения, изменив это так, чтобы экземпляр подкласса содержал свойства родительского класса.преимущество
- Решена проблема операции ссылочного типа наследования цепочки прототипов.
- Решена проблема передачи параметров родительского класса
недостаток
- Невозможно избавиться от функции достижения путем простого наследования с использованием заимствованного шаблона конструктора. Метод определен в конструкторе, и повторное использование недопустимо.
- Метод, определенный для прототипа суперкласса, недоступен для подкласса, экземпляр подкласса просто получает свойство, связанное с this суперкласса. Учитывая эти недостатки, использование только конструктора заимствования также редко используется.
наследование композиции
Вышеупомянутые два метода наследования (наследование по цепочке прототипов + наследование с заимствованием конструктора) имеют свои преимущества и недостатки, но они не идеальны.Поясним комбинированное наследование.Код:
代码实现:
function SuperType(name){
this.name=name;
this.firend=['a','b']
}
SuperType.prototype.getName=function(){
return this.name
}
function SubType(name,age){
this.age=age;
SuperType.call(this,name)
}
SubType.prototype=new SuperType();
SubType.prototype.constrcutor = SubType;
SubType.prototype.getAge=function(){
return this.age
}
var childShiny=new SubType('shiny',23);
var childRed = new SubType('red',22);
childShiny.firend.push('c');
childRed.firend.push('d');
console.log(childShiny.getName());
console.log(childShiny.getAge());
console.log(childRed.getName());
console.log(childRed.getAge());
console.log(childRed.friend);//[a,b,d]
console.log(childShiny.friend);//[a,b,c]
Фундаментальный
- Используйте реализацию наследования цепочки прототипов, чтобы удовлетворить общий метод цепочки прототипов с помощью функции поиска прототипа.
- Используйте метод заимствованного конструктора, используйте резервную копию общего родительского класса экземпляра резервного копирования
сцены, которые будут использоваться
Получение преимуществ наследования цепочки прототипов и наследования конструктора — метод наследования, признанный разработчиками, но и у него есть свои недостатки.языковая реализация
- Определите два конструктора, а именно суперкласс (SuperType) и подкласс (SubType), чтобы реализовать, что подкласс может использовать свойства суперкласса (свойства выше самого себя и прототипа). Перепишите прототип подкласса так, чтобы прототип подкласса указывал на экземпляр суперкласса, чтобы конструктор подкласса был адресом экземпляра суперкласса, а подкласс мог использовать свойства самого суперкласса и прототипа .
- Ставьте не конструктор родительского класса, а одну из функций.Так проще понять.В конструкторе подкласса позаимствуйте функцию родительского класса для выполнения, изменив это так, чтобы экземпляр подкласса содержал свойства родительского класса.
преимущество
- Решена проблема, из-за которой операция экземпляра ссылочного типа наследования цепочки прототипов приводит к изменению ссылки.
- Решен способ наследования конструктором, экземпляр подкласса прототипа родительского класса может использовать
недостаток
* Конструктор родительского класса заменяется экземпляром дважды * Экземпляр будет иметь некоторые эти свойства конструктора родительского класса, а конструктор подкласса (прототип) также будут иметь некоторые свойства экземплярапрототипное наследование
Кстати, разве описанное выше комбинированное наследование не было признано разработчиками?Что такое прототипное наследование? Давайте посмотрим, как выглядит прототипное наследование.Код:
代码实现:
1 function object(o){
function F(){};
F.prototype=o;
return new F()
}
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var personShiny = object(person);
var personRed = object(person);
console.log(personShiny.name)//Nicholas
console.log(personRed.name)//Nicholas
personShiny.friends.push('red');
personRed.friends.push('shiny');
console.log(personShiny.friends)//["Shelby", "Court", "Van","red","shiny"]
//ECMAScript 5 通过新增 Object.create()方法规范化了原型式继承。这个方法接收两个参数:一
//个用作新对象原型的对象和(可选的)一个为新对象定义额外属性的对象。在传入一个参数的情况下,
//Object.create()与 object()方法的行为相同。
2
var person = {
name: "Nicholas",
friends: ["Shelby", "Court", "Van"]
};
var personShiny = Object.create(person);
var personRed = Object.create(person);
console.log(personShiny.name)//Nicholas
console.log(personRed.name)//Nicholas
personShiny.friends.push('red');
personRed.friends.push('shiny');
console.log(personShiny.friends)//["Shelby", "Court", "Van","red","shiny"]
Фундаментальный
Чтобы создать экземпляр базового класса по методу Object.create (), __proto__ Этот экземпляр направлен базовый класс
сцены, которые будут использоваться
В случаях, когда вы просто хотите сохранить один объект похожим на другой без использования конструктораязыковая реализация
Вам нужно создать базовый объект, как базовый объект нового объекта, получить новый экземпляр с помощью метода Object или метода Object.create, этот новый экземпляр __proto__ указывает на базовый объектпреимущество
В случае отсутствия необходимости создания конструктора реализовано наследование по цепочке прототипов, а объем кода уменьшен на часть
недостаток
- Некоторые операции с эталонными данными времени будут проблематичными, два экземпляра будут наследовать общую ссылку на классы данных экземпляра.
- Тщательное определение методов, чтобы не определять методы, которые также наследуют одно и то же имя методов от прототипа объекта.
- Невозможно использовать параметры непосредственно в родительском конструкторе
паразитарное наследование
Давайте прочитаем вышеуказанный тип прототипа наследования, и на самом деле, цепь прототипа, чтобы наследовать небольшую разницу, но устранение конструктора этому, но прототипное наследование недостаточно (объект не может быть добавлен в атрибут резервного копирования), следующее паразитарное наследование ОтказКод:
代码实现:
// 和工厂模式非常类似,创建一个对象,增强一些功能并返回该对象
function createAnother(o){
var clone = Object(o);
clone.sayHi=function(){
console.log('hi')
}
return clone
}
var person = {
name:'shiny',
friends:['a','b']
}
var personShiny = createAnother(person);
console.log(personShiny.sayHi())//Ho
Фундаментальный
Создайте резервную копию объекта, затем добавьте атрибуты к резервному объекту и верните
сцены, которые будут использоваться
Реализуйте наследование без использования конструкторов, как показано ранее. Функция object(), используемая в шаблоне наследования, не требуется; в этом шаблоне работает любая функция, возвращающая новый объект.языковая реализация
Подобно конструктору, через метод выполнения внутри создается объект, добавляющий свойства и методы к объекту, а затем возвращающийпреимущество
- В случае отсутствия необходимости создания конструктора реализовано наследование по цепочке прототипов, а объем кода уменьшен на часть
- Вы можете добавить некоторые свойства к резервному объекту
недостаток
Подобно конструктору, метод создания паразита должен добавить некоторые желаемые свойства к объекту клона, которые являются некоторыми частными свойствами, помещенными в клон.
Наследование паразитарного состава
Давайте посмотрим, что вышеупомянутая композиция наследство выглядит идеально, но у него также есть недостатки (родительский класс приводится в два раза, экземпляр подкласса и конструктор подкласса имеют те же свойства), а паразитарная композиция состоит в том, чтобы решить эти проблемы.Код:
代码实现:
function inheritPrototype({SubType,SuperType}){
const prototype = Object(SuperType.prototype);
prototype.constrcutor=SubType;
SubType.prototype=prototype;
}
function SuperType(name){
this.name=name;
this.friends=['a','b']
}
SuperType.prototype.getName=function(){
return this.name;
}
function SubType(name,age){
this.age=age;
SuperType.call(this,name)
}
inheritPrototype({SubType,SuperType});
SubType.prototype.getAge=function(){
return this.age
}
var SubTypeShiny = new SubType('Shiny',23);
SubTypeShiny .friends.push('c')
var SubTypeRed = new SubType('Red',21);
SubTypeRed .friends.push('d')
console.log(SubTypeShiny.getName())//Shiny
console.log(SubTypeShiny.getAge())//22
console.log(SubTypeShiny.friends)//['a','b','c']
console.log( SubTypeRed.getName())//Red
console.log( SubTypeRed.getAge())//21
console.log( SubTypeRed.friends)//['a','b','d']
Фундаментальный
- В конструкторе подкласса методы call и apply используются для изменения this конструктора родительского класса и выполнения конструктора родительского класса, чтобы экземпляр подкласса имел некоторые свойства конструктора родительского класса.
- Объедините прототип подкласса, чтобы изменить прототип конструктора родительского класса, и укажите конструктор прототипа родительского класса на конструктор подкласса.
сцены, которые будут использоваться
Реализуйте наследование без использования конструкторов, как показано ранее. Функция object(), используемая в шаблоне наследования, не требуется; в этом шаблоне работает любая функция, возвращающая новый объект.языковая реализация
Он очень похож на комбинированный паразитический метод, за исключением того, что изменен метод наследования цепочки прототипов подкласса.Комбинированный паразитизм наследует экземпляр родительского класса.преимущество
- Реализовать наследование цепочки прототипов и заимствовать конструкторы без создания экземпляра родительского класса один раз.
- Уменьшено количество операций поиска в цепочке прототипов (подклассы напрямую наследуют прототип суперкласса, а не экземпляр суперкласса)
недостаток
Нет
Ниже приводится сравнение прототипов диаграмм композиционного наследования и паразитарного композиционного наследования.