JS的继承


一、构造函数继承

function Person() {
    this.name = 'person'
}
Person.prototype.show = function () {
  console.log('Person.show');
}

function Student() {
  this.age = 12
  this.name = 'student'
  Person.call(this)
}
Student.prototype.study = function () {
  console.log('Student.study');
}
var s1 = new Student()
var s2 = new Student()

执行

console.log('s1', s1);
console.log('s2', s2);

s1.study()
s1.show()

打印
在这里插入图片描述
结论
通过call 继承时,只能继承构造函数里面的属性,没有办法继承原型链上的方法
优点:能向父类构造函数传参数,子类实例不共享父类构造函数的引用属性
缺点:方法不能复用,子类实例不能继承父类构造函数原型上的方法

二、原型链继承

function Person() {
    this.name = 'person'
    this.arr = [1,2,3]
    this.drink = function () {
        console.log('Person.drink');
    }
}
Person.prototype.show = function () {
  console.log('Person.show');
}

function Student() {
  this.age = 12
  this.name = 'student'
}
Student.prototype = new Person()
Student.prototype.study = function () {
  console.log('Student.study');
}
var s1 = new Student()
var s2 = new Student()

执行

console.log('s1', s1);
console.log('s2', s2);

s1.arr.push(999)
s1.study()
s1.drink()
s1.show()

打印
在这里插入图片描述
结论
通过原型链继承时,如果属性是引用类型会造成数据污染
优点:共享了父类构造函数的方法
缺点:不能向父类构造函数传参数,子类实例共享父类构造函数的引用属性

三、寄生组合继承(完美)

function Person() {
    this.name = 'person'
    this.arr = [1,2,3]
    this.drink = function () {
        console.log('Person.drink');
    }
}
Person.prototype.show = function () {
  console.log('Person.show');
}

function Student() {
  this.age = 12
  this.name = 'student'
  Person.call(this)
}
Student.prototype = Object.create(Person.prototype)
Student.prototype.constructor = Student
Student.prototype.study = function () {
  console.log('Student.study');
}
var s1 = new Student()
var s2 = new Student()

执行

console.log('s1', s1);
console.log('s2', s2);

s1.arr.push(999)
s1.study()
s1.drink()
s1.show()

打印
在这里插入图片描述
结论:

  1. 一般组合继承是 Student.prototype = new Person()和Person.call(this)
    这样造成的问题是由于调用了2次父类的构造方法(call了一次,new Person()一次)会存在一份多余的父类实例属性

  2. 进行优化是让 Student.prototype = Person.prototype == (减少new Person生成多余的一份属性,子类的原型和父类的原型是同一个)==
    缺点:Child绑定新方法 通过父类原型实例化的p2 也会有新方法,
    修正Child的construction会影响Person的construction

  3. 使用 Object.create Object.create()方法用于创建一个新对象,使用现有的对象来作为新创建对象的原型(prototype)

四、多继承

function Person() {
    this.name = 'person'
    this.arr = [1,2,3]
    this.drink = function () {
        console.log('Person.drink');
    }
}
Person.prototype.show = function () {
  console.log('Person.show');
}

function Student() {
  this.age = 12
  this.name = 'student'
  Person.call(this)
  Child.call(this)
}

function Child() { 
  this.name = 'child'
  this.sex = 'man'
 }
 Child.prototype.play = function () { 
   console.log('Child.play');
}

Student.prototype = Object.create(Person.prototype)
Student.prototype = Object.assign(Student.prototype,Child.prototype)
Student.prototype.constructor = Student
Student.prototype.study = function () {
  console.log('Student.study');
}
var s1 = new Student()
var s2 = new Student()

执行

console.log('s1', s1);
console.log('s2', s2);

s1.arr.push(999)
s1.study()
s1.drink()
s1.show()
s1.play()

打印
在这里插入图片描述

结论
使用混入的方式Object.assign

参考地址:
MDN

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值