原型链实现继承的6种方式

原型链

function parent(){
    this.name = 'asd'
}
function child(){
    
}
child.prototype = new parent()
const instance = new child()
alert(instance.name)    //'asd'
复制代码

因为此模式会共享属性和方法,所以当一个实例修改属性和方法时会影响其他实例,而且子类型无法向超类型传递参数。综上,不推荐使用此模式。

借用构造函数

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

function child() {
    parent.call(this,'sda')
    this.age = 25
}

const instance = new child()
alert(instance.name) //'sda'
alert(isntance.age)  //25
复制代码

此模式解决了上一模式的存在的两个问题,但还是存在一个小问题,所以还是不推荐使用。下面是此模式的优缺点。

  1. 每一个child的实例都有name属性的副本,避免了属性修改的传染性。
  2. 子类型可以向超类型传递参数
  3. 函数无法复用

组合继承

function parent(name) {
    this.name = name
    this.colors = ['red']
}

parent.prototype.sayName = () => {
    alert(this.name)
}

function child(name, age) {
    parent.call(this, name)
    this.age = age
} 

child.prototype = new parent()
child.prototype.constructor = child
child.prototype.sayAge = () => {
    alert(this.age)
}

复制代码

此模式完美的解决了前面两种模式存在的问题,适用于绝大多数的场景,因此推荐使用该模式。

原型式继承

const person = {
    name: 'sa',
    friends: ['ad', 'da']
}
function object(original) {
    function F() {}
    F.prototype = original
    return new F()
}
//Object.create()是object()的规范实现
const anotherPerson = Object.create(person)
复制代码

该模式在一个对象的基础上创建一个类似的对象,优点是可以节省书写构造函数的代码。由于还是同原型式一样共享属性和方法,所以也具有原型式的问题。

寄生式继承

var person = {
    name: 'sa',
    friends: ['ad', 'da']
}

function createAnother(original) {
    const clone = Object.create(original)
    clone.say = () => {
        alert('hello')
    }
}
var anotherPerson = createAnother(person)
anotherPerson.say();  //hello
复制代码

该模式类似于原型式继承,不过这模式在内部实现了增强对象,而且此模式使用于任何返回新对象的函数,所以推荐使用。

寄生组合式继承

function inheritPrototype(child, parent) {
    const portotype = Object.create(parent)
    prototype.constructor = child 
    child.prototype = prototype
}
复制代码

由于该模式只调用了一次parent构造函数,因此避免了组合式调用两次parent构造函数所创建的不必要的、多余的属性。该模式可谓是结合了寄生式继承和组合式继承两种模式的优点,是上述模式的集大成者,所以该模式被广泛认为是引用类型最理想的继承范式。

转载于:https://juejin.im/post/5b98df07f265da0af1612695

你可能感兴趣的:(原型链实现继承的6种方式)