继承,是面向对象编程很重要的思想
一、原型继承
原型链继承: 即用孩子的原型链保存一个父亲实例
function Parent() { this.name = 'parent1' this.play = [1, 2, 3] } Parent.prototype.getName = function() { consolo.log(this.name) } function Child(name) { this.name = name }
Child.prototype = new Parent()
|
但是这种继承会共享父类的数据, 所以一改全改
let s1 = new Child('s1') let s2 = new Child('s2') s1.play s2.play
s1.push(4) s1.play s2.play
|
二、借用构造函数继承
为了解决原型链继承中数据共享的问题
function Parent(name) { this.name = name this.play = [1,2,3] } Parent.prototype.getName = function(name) { console.log(name) }
function Child(name) { Parent.call(this) } let s1 = new Child('s1') let s2 = new Child('s2') s1.play.push(4) s1.play s2.play
|
但是新的问题又出现了
因为,getName定义在Parent的原型上, 因此,因此没有Parent的实例,那么Child是访问不了
因此,弊端是不能继承原型上的方法
三、组合继承 (前面两种结合)
function Parent(name) { this.name = name this.play = [1,2,3] } Parent.prototype.getName = function() { console.log(this.name) }
function Child(name) { Parent.call(this) this.name = 'child' }
Child.prototype = new Parent('parent')
Child.prototype.constructor = Child
let s1 = new Child() let s2 = new Child() s1.play.push(4) s1.play s2.play
s1.getName() s2.getName()
|
完美? 不, 还是有些问题
Parent被调用了两次
Parent.call(this) new Parent()
|
四、原型式继承
通过Object.create(parent)指定对象作为原型
let Parent = { name: 'parent', play: [1,2,3], getName: function(){ return this.name } } let child = Object.create(parent)
child.name = 'child' child.play.push(4) let child1 = Object.create(parent)
child.play child1.play
|
因此,和第一种一样存在共享数据的问题
五、寄生式继承
主要是为了能够灵活添加方法
将Objec.create()产生的对象当作宿主
let Parent = { name: 'parent', play: [1,2,3], getName: function(){ return this.name } } function clone(original){ let clone = Object.create(original) clone.getPlay = function(){ return this.name } return clone }
let child = clone(Parent)
|
六、寄生组合式继承
用于解决组合式继承中两次调用Parent的问题
function clone(parent,child){ child.prototype = Object.create(parent,prototype) child.prototype.constructor = child; }
function Parent(){ this.name = 'parent' this.play = [1,2,3] } Parent.prototype.getName = function(){ return this.name }
function Child(){ Parent.call(this) this.name = 'child' } Child.prototype.getPlay = function(){ return this.play } let child = new Child() let child1 = new Child()
|
ES6的 extends继承
通过babel转码也是寄生组合式继承的代码