一、准备代码
var Parent = function() {
this.name = '父亲的名字'
}
Parent.prototype.getName = function() {
return this.name
}
var Child = function() {
}
二、原型链继承
原理:将Child的prototype与Parent的实例关联起来 Child就可以直接拿到Parent里面的东西了
关键代码:
Child.prototype = new Parent()
Child.prototype.construct = Child
实验一下:
var child = new Child()
console.log(child.name)// 输出 父亲的名字
console.log(child.getName) //输出 父亲的名字
很明显,Child的实例拿到了Parent里的东西。
原型链继承缺点
原型链继承虽然拿到里面的东西,但是当Parent里面的值是引用类型时,实例改变了引用对象里值时,其他实例拿到的值也会改变。
实验一下:
将 一 中的代码修改一下:
var Parent = function() {
this.name = {
fatherName: '父亲的名字'
}
}
Parent.prototype.getName = function() {
return this.name
}
var Child = function() {
}
var child = new Child()
console.log(child.name)
console.log(child.getName)
var child1 = new Child()
var child2 = new Child()
child2.name.fatherName = 'child2 name'
console.log(child1.name.fatherName) // child1.name.fatherName 的值随着改变
二、构造函数继承
将这行代码更改到上面 :
var Child = function() {
Parent.call(this, 'Child name')
}
结果:
var child1 = new Child()
var child2 = new Child()
child1.name.fatherName = 'child1 name'
child2.name.fatherName = 'child2 name'
console.log(child1.name.fatherName) // child1 name
console.log(child2.name.fatherName) // child2 name
console.log(child2.getName()) // 报错
构造函数继承缺点
构造函数继承 能够拿到 Parent 的属性,并且不会更改其他实例的拿到的数据。但是缺点也很明显:
这个方法拿不到 Parent.prototype 上面的方法。
三、组合式继承
顾名思义:将上面两种方法结合起来:这样既可以用 原型链继承 得到属性,也可以用 构造函数继承 得到方法。
var Parent = function() {
this.name = {
fatherName: '父亲的名字'
}
}
Parent.prototype.getName = function() {
return this.name
}
var Child = function() {
Parent.call(this, 'Child name')
}
Child.prototype = new Parent()
Child.prototype.construct = Child
var child1 = new Child()
var child2 = new Child()
child2.name.fatherName = 'child2 name'
child1.name.fatherName = 'child1 name'
console.log(child1.name.fatherName)
console.log(child2.name.fatherName)
console.log(child2.getName()) // {fatherName: "child2 name"}
组合式继承缺点
但是这样又会有个新的问题,每一次创建Child的实例时,就会new Parent(),很显然这样会造成资源的浪费。
四、寄生组合式继承
寄生组合式继承实现方法:
Child.prototype = new Parent()
改为:
Child.prototype = Parent.prototype
因为 Parent的实例中的__proto__里面有Parent的prototype,所以这样做就解决了组合式继承的缺点
寄生组合式缺点:
很明显,如果这样做,会导致如果我们只想使用Parent的时候,会看到Child往里面添加的方法,所以每个构造函数都要持有自己的专有的prototype对象
修改寄生组合式缺点:
Child.prototype = Object.create(Parent.prototype)
通过创建一个新的中间对象,将该对象的prototype指向Parent.prototype,这样做避免了调用Patent的构造方法产生对象,又可以使Child能够访问到Prarent的prototype,并且,如果Child.prototype添加了属性、方法,也只会挂在这个中间对象的prototype上面,并不会影响到构造函数的prototype