JS继承方式:原型链 、构造函数、类

方式一:原型链继承

弊端:这种模式存在问题,子类实例共享了父类实例的属性,导致修改一个子类实例的属性值,其他子类实例的属性值也修改了。

function Parent() {
  //注意类型使用引用类型
  this.name = ['zhangsan']
}
Parent.prototype.getName = function () {
  return this.name
}

function Child() {
  
}
Child.prototype = new Parent()

let child1 = new Child()
let child2 = new Child()

//测试修改子类实例,是否影响其他子类实例
child1.name[0] = 'lisi'
console.log(child1.name) // ['lisi']
console.log(child1.getName())// ['lisi'] 
console.log(child2.name)// ['lisi'] 
console.log(child2.getName())// ['lisi'] 
console.log(child1,child2)

方式二:构造函数继承

弊端:这种模式解决了原型链继承共享属性的问题,但是无法继承父类原型上的方法。

function Parent() {
  //注意类型使用引用类型
  this.name = ['zhangsan']
}
Parent.prototype.getName = function () {
  return this.name
}
function Child() {
  Parent.call(this)
}

let child1 = new Child()
let child2 = new Child()

//测试修改子类实例,是否影响其他子类实例
child1.name[0] = 'lisi'
console.log(child1.name) // ['lisi']
console.log(child2.name)// ['zhangsan'] 
console.log(child1.getName())// 报错
console.log(child2.getName())// 报错 
console.log(child1,child2)

 方式三:原型类和构造函数组合继承

优点:这种模式解决了原型链继承共享属性的问题,并且可以继承父类原型上的方法。

function Parent() {
  console.log('父类')
  
  //注意类型使用引用类型
  this.name = ['zhangsan']
}
Parent.prototype.getName = function () {
  return this.name
}
function Child() {
  Parent.call(this)
}
Child.prototype = new Parent()

let child1 = new Child()
let child2 = new Child()

//测试修改子类实例,是否影响其他子类实例
child1.name[0] = 'lisi'
console.log(child1.name) // ['lisi']
console.log(child2.name)// ['zhangsan'] 
console.log(child1.getName())//['lisi']
console.log(child2.getName())// ['zhangsan']
console.log(child1,child2)

方式四:寄生组合继承

有组合继承的优点,还减少一次父类的调用

function Parent() {
  console.log('父类')
  //注意类型使用引用类型
  this.name = ['zhangsan']
}
Parent.prototype.getName = function () {
  return this.name
}
function Child() {
  Parent.call(this)
}

//这种写法导致子类的属性和方法变动会影响父类
// Child.prototype = Parent.prototype
// Child.prototype.constructor = Child
//解决方法使用Object.create()
Child.prototype = Object.create(Parent.prototype)

let child1 = new Child()
let child2 = new Child()

//测试修改子类实例,是否影响其他子类实例
child1.name[0] = 'lisi'
console.log(child1.name) // ['lisi']
console.log(child2.name)// ['zhangsan'] 
console.log(child1.getName())//['lisi']
console.log(child2.getName())// ['zhangsan']
console.log(child1,child2)

//测试修改子类实例,是否影响父类实例
Child.prototype.getName1 = function () {
  return this.name
}

let p = new Parent()
console.log(p)

方式五:使用Class、extends

class Parent {
  constructor() {
    this.name = ['zhangsan']
  }
  getName() {
    return this.name
  }
}

class Child extends Parent {
  constructor() {
    super()
  }
}

let child1 = new Child()
let child2 = new Child()

//测试修改子类实例,是否影响其他子类实例
child1.name[0] = 'lisi'
console.log(child1.name) // ['lisi']
console.log(child2.name)// ['zhangsan'] 
console.log(child1.getName())//['lisi']
console.log(child2.getName())// ['zhangsan']
console.log(child1,child2)

//测试修改子类实例,是否影响父类实例
Child.prototype.getName1 = function () {
  return this.name
}

let p = new Parent()
console.log(p)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值