原型链继承
下面的例子中想解决的问题是,下面的函数也想拥有上面函数中的属性
function Father() {
this.name = 'father'
}
Father.prototype.getFatherName = function() {
return this.name
}
function Son() {
this.age = 12
}
Son.prototype.getSonName = function() {
return this.name
}
var son = new Son();
console.log(son.getFatherName()) // son.getFatherName is not a function
原型链继承之后,看下面
Son.prototype = new Father()
// 这里相当于它重写了这个类的原型对象,他的原型对象本来拥有指向他的构造函数的指针,现在却指向了
另一个类的的实例,而实例对象又有指向原型对象的指针,说明它拥有了另一个类的原型链上的属性和方法。
Son.prototype.getSonName = function() {
return this.name
}
var son = new Son();
console.log(son.getFatherName()) // father
注意⚠️
上面的例子中,重写原型对象只能用那种方式,如果用对象字面量的话,就会有问题,具体看下面
function Father() {
this.name = 'father'
}
Father.prototype.getFatherName = function() {
return this.name
}
function Son() {
this.age = 12
}
Son.prototype = {
name: 'father',
getSonName: function() {
return this.name
}
}
var son = new Son();
console.log(son.getFatherName()) // son.getFatherName is not a function
这里son的实例对象已经指向了Object对象,他已经切断了Son和Father的联系
原型链继承的弊端, 属性会共享,相互影响
a从b继承来的属性c,a要是改了c,实例出来的d的属性c也变成了改变后的值
eg
function Father() {
this.arrs = [1,2,3]
}
function Son() {
this.age = 12
}
Son.prototype = new Father()
var son1 = new Son();
son1.arrs.push(4)
console.log(son1.arrs) // [ 1, 2, 3, 4 ]
var son2 = new Son();
console.log(son2.arrs) // [ 1, 2, 3, 4 ]
借用构造函数继承(call,apply)
function Father() {
this.arrs = [1,2,3]
}
function Son() {
Father.apply(this)
}
var son1 = new Son();
son1.arrs.push(4)
console.log(son1.arrs) // [ 1, 2, 3, 4 ]
var son2 = new Son();
console.log(son2.arrs) // [ 1, 2, 3 ]
这个就会解决上面的问题
组合继承
借用构造函数实现实例属性的继承,使用原型链条实现原型属性和方法的继承