Внешний интерфейс должен знать наследство 7 ES5 и ES6.

JavaScript

Как мы все знаем, вES6Раньше не было синтаксического сахара для классов во фронтэнде, поэтому его нельзя было использовать как другие языки.extendsКлючевым словом является получение отношения наследования, и для достижения наследования необходимы некоторые дополнительные методы. Ниже приведены некоторые часто используемые методы.Красная книга была обобщена очень всесторонне, поэтому эта статья в основном является примечанием и прочесыванием главы Красной книги о наследовании.

Наследование цепочки прототипов

function Parent() {
    this.name = 'arzh'
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child() {
    
}

//主要精髓所在
Child.prototype = new Parent()
Child.prototype.constructor = Child

var arzhChild = new Child()

arzhChild.getName() // 'arzh'

Недостатки наследования цепочки прототипов:

  1. Модификация каждого экземпляра свойства ссылочного типа будет использоваться другими экземплярами.
function Parent() {
    this.names = ['arzh','arzh1'];
}

function Child() {
    
}

//主要精髓所在
Child.prototype = new Parent()
Child.prototype.constructor = Child

var arzhChild2 = new Child()
arzhChild2.names.push('arzh2')
console.log(arzhChild2.names) //[ 'arzh', 'arzh1', 'arzh2' ]

var arzhChild3 = new Child()
arzhChild3.names.push('arzh3')
console.log(arzhChild3.names) //[ 'arzh', 'arzh1', 'arzh2', 'arzh3' ]
  1. при созданииChildнапример, невозможноParentПередать параметры. Это сделаетChildЭкземпляры не могут настраивать свои собственные свойства (имена)

Заимствованные конструкторы (классическое наследование)

function Parent() {
    this.names = ['arzh','arzh1']
}

function Child() {
    Parent.call(this)
}

var arzhChild2 = new Child()
arzhChild2.names.push('arzh2')
console.log(arzhChild2.names) //[ 'arzh', 'arzh1', 'arzh2' ]

var arzhChild3 = new Child()
arzhChild3.names.push('arzh3')
console.log(arzhChild3.names) //[ 'arzh', 'arzh1', 'arzh3' ]

преимущество:

  1. Решена проблема, заключающаяся в том, что модификация каждого экземпляра атрибута ссылочного типа будет использоваться другими экземплярами.
  2. Подклассы могут передавать параметры родительским классам
function Parent(name) {
    this.name = name
}

function Child(name) {
    Parent.call(this, name)
}
    
var arzhChild = new Child('arzh');

console.log(arzhChild.name); // arzh

var arzhChild1 = new Child('arzh1');

console.log(arzhChild1.name); // arzh1

недостаток:

  1. Невозможно повторно использовать публичные функции родительского класса
  2. Каждый раз, когда подкласс создает экземпляр, функция родительского класса должна выполняться один раз.

Композиционное наследование (наследование цепочки прототипов и слияние заимствованных конструкторов)

function Parent(name) {
    this.name = name
    this.body = ['foot','hand']
}

function Child(name, age) {
    Parent.call(this, name)
    this.age = age
}

Child.prototype = new Parent()
Child.prototype.constructor = Child

var arzhChild1 = new Child('arzh1', '18')
arzhChild1.body.push('head1')
console.log(arzhChild1.name,arzhChild1.age) //arzh1 18
console.log(arzhChild1.body) //[ 'foot', 'hand', 'head1' ]

var arzhChild2 = new Child('arzh2', '20')
arzhChild2.body.push('head2')
console.log(arzhChild2.name,arzhChild2.age) //arzh2 20
console.log(arzhChild2.body) //[ 'foot', 'hand', 'head2' ]

преимущество:

  1. Решена проблема, заключающаяся в том, что модификация каждого экземпляра атрибута ссылочного типа будет использоваться другими экземплярами.
  2. Подклассы могут передавать параметры родительским классам
  3. Повторно используемый метод родительского класса

недостаток:

  1. Конструктор родительского класса необходимо выполнить дважды, первый разChild.prototype = new Parent(), второй разParent.call(this, name)привести к ненужным тратам

прототипное наследование

Скопируйте входящий объект в прототип созданного объекта, таким образом реализуя наследование

function createObj(o) {
    function F(){}
    F.prototype = o;
    return new F();
}
var person = {
    name : 'arzh',
    body : ['foot','hand']
}
var person1 = createObj(person)
var person2 = createObj(person)

console.log(person1) //arzh
person1.body.push('head') 
console.log(person2) //[ 'foot', 'hand', 'head' ]

Недостатки: как и наследование цепочки прототипов,Модификация каждого экземпляра свойства ссылочного типа будет использоваться другими экземплярами.

паразитарное наследование

мы можем использоватьObject.createВместо вместо вышеперечисленногоcreateObjПринцип в основном тот же. На самом деле паразитарное наследованиеcreateObjВнутренняя часть объекта улучшает объект в той или иной форме (улучшение здесь можно понимать как метод добавления объекта) и, наконец, возвращает улучшенный объект.

function createEnhanceObj(o) {
    //代替原型式继承的createObj
    var clone = Object.create(o)
    clone.getName = function () {
        console.log('arzh')
    }
    return clone;
}

пройти черезcreateEnhanceObjВы можете наследовать методы объекта таким образом, когда создаете объект.
Недостаток: Как и в случае с заимствованными конструкторами,Невозможно повторно использовать функции родительского класса, методы будут создаваться каждый раз при создании объекта.

Паразитическая композиционная наследственность

Нет необходимости в дополнительных прототипах для подклассовnewКак только конструктор родительского класса, такой какChild.prototype = new Parent()Просто скопируйте копию прототипа родительского класса в прототип дочернего класса.

function inheritPrototype(Parent, Child){
	Child.prototype = Object.create(Parent.prototype) //创建父类原型的一个副本,把副本赋值给子类原型
	Child.prototype.constructor = Child;
}

function Parent(name) {
    this.name = name
}

Parent.prototype.getName = function () {
    console.log(this.name)
}

function Child(color) {
    Parent.call(this, 'arzh')
    this.color = color
}

inheritPrototype(Parent, Child)

var arzhChild = new Child('red')
console.log(arzhChild.name) // 'arzh'

Преимущество: нет необходимости вызывать конструктор супертипа, чтобы указать прототип подтипа.

Наследование ES6

ES6Поддерживает наследование через классы, способ относительно простой, код следующий

class Point {
    constructor(x, y) {
        this.x = x
        this.y = y
    }
    
    toString() {
        return this.x + '' + this.y
    }
}

class ColorPoint extends Point {
    constructor(x, y, color) {
        super(x, y) //调用父类的constructor(x, y)
        this.color = color
    }
    
    toString() {
        return this.color + ' ' + super.toString() // 调用父类的toString()
    }
}

var colorPoint = new ColorPoint('1', '2', 'red')

console.log(colorPoint.toString())  // red 12

Если у вас есть какие-либо предложения по оптимизации этой статьи, вы можете отсканировать приведенный ниже QR-код для совместного обсуждения.В то же время я надеюсь, что вы будете уделять больше внимания и будете время от времени присылать оригинальные статьи.

Категории