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')