В конце 9021 года мне вдруг захотелось подготовиться к этому последнему месяцу, попробовать возможность и посмотреть, сможем ли мы пойти дальше. Поэтому я начал готовить некоторые базовые знания, а также обобщать их для студентов, которые хотят сменить работу. Надеюсь, вы все сможете найти работу, которую хотите. Удачи всем!
1. Что такое наследование
Класс получает свойства или методы другого класса или классов. Наследование позволяет подклассам иметь различные методы и свойства родительского класса. Чтоб не повторять вывод большого количества кода.
Принцип наследования
Скопируйте методы и свойства родительского класса, чтобы переопределить объект-прототип дочернего класса.
3. Наследование цепочки прототипов
3.1 Реализация
function Father() {
this.text = '1';
}
Father.prototype.someFn = function() {
console.log(1);
}
Father.prototype.someValue = '2';
function Son(){
this.text1 = 'text1';
}
// 函数原型指向构造函数的实例
Son.prototype = new Father();
3.2 Преимущества
1. Простота и удобство в эксплуатации.
3.3 Недостатки
1. Свойства, объявленные родительским классом с помощью this, являются общими для всех экземпляров. Причина в том, что инстанцирование — это одноразовое присвоение родительского класса прототипу экземпляра подкласса, и оно также присваивает свойства, объявленные родительским классом через это, прототипу подкласса. Например, значение массива в родительском классе, в нескольких экземплярах подкласса, независимо от того, какой экземпляр изменяет значение массива, это повлияет на другие экземпляры подкласса.
2. При создании экземпляра подкласса нельзя передавать параметры конструктору родительского класса, что недостаточно гибко.
В-четвертых, позаимствовать конструктор (вызов)
4.1 Реализация
function Father(...arr) {
this.some = '父类属性';
this.params = arr;
}
Father.prototype.someFn = function() {
console.log(1);
}
Father.prototype.someValue = '2';
function Son(fatherParams, ...sonParams) {
// Father的this指向Son的this
// 使用call调用父类,Father将会立即被执行,并且将父类的Father的this执行Son
// 的this。实例化子类,this将指向new期间创建的新对象,返回该新对象。
Father.call(this, ...fatherParams);
this.text = '子类属性';
this.sonParams = sonParams;
}
var fatherParams = [];
var sonParams = [];
var sonInstance = new Son(fatherParams, ...sonParams);
4.2 Преимущества
1. Вы можете передавать параметры родительскому классу.
2. Решить проблему, заключающуюся в том, что свойства, объявленные родительским классом, будут общими для экземпляров.
4.3 Недостатки
1. Наследоваться могут только свойства/методы, объявленные родительским классом. Невозможно наследовать свойства/методы прототипа родительского класса.
2. Метод родительского класса нельзя использовать повторно. Каждый раз, когда создается экземпляр подкласса, выполняется функция суперкласса. Повторное объявление метода, определенного родительским классом, нельзя использовать повторно.
5. Комбинированное наследование (вызов+новый)
Принцип: наследовать свойства и методы этого и прототипа объекту-прототипу подкласса посредством наследования цепочки прототипов. Используйте заимствованный конструктор, чтобы наследовать свойства и методы, объявленные родительским классом, через this в свойствах экземпляра дочернего класса.
5.1 Реализация
function Father(...arr) {
this.some = '父类属性';
this.params = arr;
}
Father.prototype.someFn = function() {
console.log(1);
}
Father.prototype.someValue = '2';
function Son(fatherParams, ...sonParams) {
// 借用构造函数继承父类this什么的属性和方法到子类实例属性上
Father.call(this, ...fatherParams);
this.text = '子类属性';
this.sonParams = sonParams;
}
// 原型链继承,将`this`和`prototype`声明的属性/方法继承至子类的`prototype`上
Son.prototype = new Father('xxxxx');
var fatherParams = [];
var sonParams = [];
var sonInstance = new Son(fatherParams, ...sonParams);
5.2 Преимущества
1. Решите проблему, связанную с тем, что свойства или методы, объявленные цепочкой прототипов, наследуются от родительского класса, которые являются общими.
2. Решить проблему заимствования конструктора для решения проблемы не наследования свойств/методов объекта-прототипа родительского класса.
5.3 Недостатки
1. Функция родительского класса вызывается дважды, что вызывает определенные проблемы с производительностью.
2. Поскольку родительский класс вызывается дважды, свойства и методы, объявленные родительским классом через this, генерируются дважды.
3. Контекст цепочки прототипов теряется, а свойства и методы, объявленные подклассом и суперклассом через прототип, существуют на прототипе подкласса.
6. Наследование прототипов
6.1 Реализация
function cloneObj(obj) {
function F(){};
// 将被继承的对象作为空函数的prototype
F.prototype = obj;
// 返回new期间创建的新对象,此对象的原型为被继承的对象,
// 通过原型链查找可以拿到被继承对象的属性
return new F();
}
6.2 Преимущества
1. Хорошая совместимость, простейшее наследование объектов.
6.3 Недостатки
1. Сколько экземпляров совместно используют унаследованные свойства, имеет место случай подделки и невозможность передачи параметров.
7. Паразитическое наследование (инкапсуляция процесса наследования)
Создайте функцию, которая используется только для инкапсуляции процесса наследования, измените функцию, чтобы каким-то образом улучшить объект внутри, и, наконец, вернуть объект. Усовершенствованные объекты на основе прототипного наследования.
7.1 Реализация
function createAnother(original){
var clone = cloneObject(original); // 继承一个对象 返回新函数
// do something 以某种方式来增强对象
clone.some = function(){}; // 方法
clone.obkoro1 = '封装继承过程'; // 属性
return clone; // 返回这个对象
}
7.2 Преимущества
1. Хорошая совместимость, простейшее наследование объектов.
7.3 Недостатки
1. Сколько экземпляров совместно используют унаследованные свойства, имеет место случай подделки и невозможность передачи параметров.
Восьмое, паразитарное комбинированное наследование (вызов + паразитарная упаковка)
1. Используйте заимствованный конструктор для наследования свойств и методов, объявленных родительским классом this. 2. Используйте паразитное наследование, чтобы установить прототип родительского класса в качестве прототипа прототипа дочернего класса, чтобы наследовать свойства и методы родительского класса.
8.1 Реализация
function Father(...arr) {
this.some = '父类属性';
this.params = arr;
}
Father.prototype.someFn = function() {
console.log(1);
}
Father.prototype.someValue = '2';
function Son() {
Father.call(this, 'xxxx');
this.text = '2222';
}
function inhertPro(son, father){
// 原型式继承
var fatherPrototype = Object.create(father.prototype);
// 设置Son.prototype的原型是Father.prototype
son.prototype = fatherPrototype;
// 修正constructor 指向
// constructor的作用:返回创建实例对象的Object构造函数的引用。
// 在这里保持constructor指向的一致性
son.prototype.constructor = son;
}
inhertPro(Son, Father);
var sonInstance = new Son();
8.2 Преимущества
1. Паразитическое комбинированное наследование является наиболее зрелым методом наследования в настоящее время, а также широко используемым методом наследования, который используется в качестве схемы наследования в большинстве Js-фреймворков.
Преимущества паразитарного композиционного наследования по сравнению с композиционным наследованием:
1. Вызов конструктора родительского класса только один раз, что снижает производительность.
2. Избегайте создания ненужных атрибутов.
3. Использование прототипного наследования гарантирует, что контекст цепочки прототипов останется неизменным: прототип подкласса имеет только свойства и методы, объявленные подклассом через прототип, а прототип родительского класса — только свойства и методы объявленный родительским классом через прототип.
Девять, ES6-расширяет наследование
9.1 Реализация
ES6 может использовать ключевое слово extends для достижения наследования, что намного понятнее и методичнее, чем реализация наследования через модифицированную цепочку прототипов ES5.
class Point{}
class ColorPoint extends Point{}
9.2 Внимание
Подкласс должен подставить суперметод в метод конструктора, иначе новый экземпляр сообщит об ошибке, потому что этот объект подкласса должен сначала пройти пластичность через конструктор родительского класса, получить свойства и методы родительского класса , а затем примените Processing, а также собственные свойства и методы подкласса. Если суперметод не вызывается, подкласс не получит этот объект. Если метод конструктора не определен, этот метод будет добавлен по умолчанию.
9.3 Преобразование
Принцип наследования ES6 такой же, как и у наследования паразитарной композиции. Преимущества и недостатки аналогичны.
Преобразование кода ES6 в ES5www.babeljs.cn/repl
Перед преобразованием:
class Point{}
class ColorPoint extends Point{}
После преобразования:
function _inherits(subClass, superClass) {
if (typeof superClass !== "function" && superClass !== null) {
throw new TypeError("Super expression must either be null or a function");
}
subClass.prototype = Object.create(superClass && superClass.prototype, {
constructor: {
value: subClass, writable: true, configurable: true
}
});
if (superClass) _setPrototypeOf(subClass, superClass);
}
9.4 Различия
Суть наследования ES5 заключается в том, чтобы сначала создать экземпляр объекта this подкласса, а затем добавить к this метод суперкласса.
Суть наследования ES6 заключается в том, чтобы сначала добавить к этому объекту экземпляра родительского класса методы и свойства, а затем использовать конструктор подкласса для его изменения.
Ссылаться на
- Основы JS — Наследование
- продвинутое программирование на JavaScript