【继承系列】JS中的寄生组合继承

1.寄生组合继承

我们先看下上次说到的组合继承缺点

  • 父类构造函数会被调用两次
  • 生成了两个实例(子类实例,和子类原型对象)

那现在我们需要跳过执行new Parent(),并且直接继承父类原型链上属性

也就是说,我们需要一个干净的实例对象,来作为子类的原型。并且这个干净的实例对象还得能继承父类的属性。

这就需要知道Object.create()的用法了

Object.create(proto, propertiesObject)

参数:

  • proto:新创建对象的原型对象。
  • propertiesObject:可选。如果没有指定为 undefined,则是要添加到新创建对象的不可枚举(默认)属性(即其自身定义的属性,而不是其原型链上的枚举属性)对象的属性描述符以及相应的属性名称。这些属性对应Object.defineProperties()的第二个参数。

返回值:

一个新对象,带着指定的原型对象和属性。

例外:

如果propertiesObject参数是null或非原始包装对象,则抛出一个 TypeError 异常。

看一个🌰:

function A(){
  this.name = 'aaa'
}

const o;

// 创建一个原型为A的空对象
o = Object.create(A.prototype);

o.__proto__ === A.prototype // true

明白他的使用了吧,当然你可能会有疑问为什么不用const o = {},因为这种方式创建的对象o.__proto__ --> Object.prototype,自己可以尝试下,对create详解请移步MDN。

1.1 题目一

理解寄生组合继承的用法

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

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

function Child (name) {
  this.sex = 'boy'
  Parent.call(this, name)
}

// 组合继承
// Child.prototype = new Parent()

// 与组合继承的区别
Child.prototype = Object.create(Parent.prototype)

const child1 = new Child('child1')

console.log(child1)
child1.getName()

console.log(child1.__proto__)

答案:

Child {sex: "boy", name: "child1"}
child1
Parent {}

可以看到,上面👆这道题就是一个标准的寄生组合继承,它与组合继承的区别仅仅是Child.prototype不同。

理解:

  • 使用寄生组合继承,child1不仅仅有自己的实例属性sex,而且还复制了父类中的属性name
  • 寄生组合继承使得实例child1能通过原型链查找,使用到Parent.prototype上的方法,因此打印出child1。

现在我们看看组合继承的缺点还存在不存在

function Parent (name) {
  console.log(name) // 这里有个console.log()
  this.name = name
}

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

// 这里改成寄生组合继承
Child.prototype = Object.create(Parent.prototype)

const child1 = new Child('child1')

console.log(child1)
console.log(Child.prototype)

惊喜来了,缺点已被干掉

child1
Child {name: "child1"}
Parent {}

然后我们画下寄生组合继承的图

在这里插入图片描述

2.总结

寄生组合继承

  • 优点
    • 只调用了一次父类构造函数,只创建了一份父类属性
    • 子类可以用到父类原型链上的属性和方法

参考文章:

48道原型题目

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值