【js 知识 】js 实现继承的几种方法以及优缺点

273 阅读1分钟
利用构造函数实现继承
  • 利用 call 拿到父构造函数的 this;
function Parent () {
    this.name = 'breeze',
    this.age = 18
}
function Child () {
    Parent.call(this)
    this.address = 'shanghai'
}
var test = new Child1()
  • 缺点是如果 Parent 在原型链上面添加方法或者属性,是无法继承的。
利用原型链来实现继承
  • 利用 prototype 的方法来实现继承
function Parent () {
    this.name = 'breeze',
    this.age = 18,
    this.offer = [1, 2, 3]
}
Parent.prototype = {
  say () {
    console.log('say')
  }
}
function Child () {
    this.address = 'shanghai'
}
Child.prototype = new Parent()
let test1 = new Child();
let test2 = new Child();
  • 缺点是如果改变了引用地址的值,所以的继承都会改变,如下:
let test1 = new Child();
let test2 = new Child();
test1.offer.push(4);
console.log(test1.offer) // [1, 2, 3, 4]
console.log(test2.offer) // [1, 2, 3, 4] (希望大家都能多多的拿 offer)
组合继承
  • 利用 call 和 prototype 来实现继承
function Parent () {
    this.name = 'breeze',
    this.age = 18
}
function Child () {
    Parent.call(this)
    this.address = 'shanghai'
}
Child.prototype = new Parent()
let test1 = new Child();
let test2 = new Parent();
console.log(test1.constructor) // Parent
console.log(test2.constructor) // Parent
  • 缺点:分不清构造函数是哪一个了,还有两次 new Parent() 性能浪费
组合继承优化
Child.prototype = new Parent()
替换成 Child.prototype = Parent.prototype 
  • 缺点是依旧存在构造函数分不清的错误
  • 原因是因为因为 Child.prototype = Parent.prototype,而 Parent.prototype 的 constructor 肯定是指向自己的;
组合继承
  • 利用 Object.create 来实现继承
function Parent () {
    this.name = 'breeze',
    this.age = 18
}
function Child () {
    Parent.call(this)
    this.address = 'shanghai'
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child // 注意这边的构造函数,如果不加的话还是 Parent
let test1 = new Child();
  • 值得说一下的是组合继承是没有办法通过 Child.prototype.constructor = Child 来改变构造函数的,因为这样会造成 Parent 的混乱。