继承的几种方式

1.借助构造函数实现继承

function Parent() {
this.name = 'parent'
}
Parent.prototype.say = function () { // 不能被继承
this.say = function() {
console.log('hello'+ this.name)
}
}
function Child() {
Parent.call(this)
this.type = 'child'
}
console.log(new Child) // 没有参数可以不写最后的()

call方法改变了函数运行的上下文(this的指向,指向了Child实例化的对象引用),将父级构造函数的this指向子类构造函数的实例上去。执行时父类的方法和属性都挂载到Child类的实例上

缺点:
父类的原型对象上有属性和方法不能被子类继承

 

2.借助原型链实现继承

function Parent2() {
this.name = 'parent2'
this.list = [1,2,5]
}
Parent2.prototype.say = function () { // 不能被继承
this.say = function() {
console.log('hello'+ this.name)
}
}
function Child2() {
this.type = 'child'
}
Child2.prototype = new Parent2()
var c21 = new Child2()
var c22 = new Child2()

// 缺点
c21.list.push(6)
console.log(c22.list) // [1, 2, 5, 6]

prototype就是让Child的实例可以访问到原型链上

根据原型链
由 Child2.prototype = new Parent2()
和 c21.__proto__ === Child2.prototype
得 c21.__proto__ 指向了new Parent2()
所以 c21.__proto__.__proto__ 与 new Parent2().__proto__为同一个对象
又因为 new Parent2().__proto__ === Parent2.prototype
所以c21.__proto__.__proto__指向 Parent2.prototype

缺点:
原型链中的原型对象是公用的

 

3.组合继承

function Parent3() {
this.name = 'parent3'
this.list = [1,2,5]
}
function Child3() {
Parent3.call(this)
this.type = 'child3'
}
Child3.prototype = new Parent3()
var c3 = new Child3()

缺点:
Parent3()执行了两次,一次在Child3()里面,一次是给Child2.prototype赋值时

 

 

4. 组合继承优化1

function Parent4() {
this.name = 'parent4'
this.list = [1,2,5]
}
function Child4() {
Parent5.call(this)
this.type = 'child4'
}
Child4.prototype = Parent4.prototype
var c4 = new Child4()

// 缺点
console.log(c31.__proto__.constructor) // Parent4

缺点:
因为Child4.prototype = Parent4.prototype,所以Child4没有构造器,是从父类继承的

 

 

5. 组合继承优化2

function Parent5() {
this.name = 'parent5'
this.list = [1,2,5]
}
function Child5() {
Parent5.call(this)
this.type = 'child5'
}
Child5.prototype = Object.create(Parent5.prototype)
Child5.prototype.constructor = Child5 
var c5 = new Child5()

缺点:
。。。可能就是比较麻烦吧

 

6.ES6实现继承(与5的效果相同)

class Animal {
  constructor(name='animal') {
    this.name = name
  }
  eat () {
    console.log('I can eat')
  }
}

class Dog extends Animal {
  constructor(name='dog') {
    super(name)
  }
  bark() {
    console.log('bark')
  }
}

let dog1 = new Dog 
let dog2 = new Dog('dd')

 

posted @ 2019-01-28 18:49  南曦  阅读(138)  评论(0编辑  收藏  举报