构造函数继承
在子类构造函数中使用 Parent.call(this)
缺点:不能继承父类的原型,所以不是真正的继承
Parent.prototype.family = "罗斯柴尔德家族"
function Parent() {
this.name = "parent"
}
function Child() {
Parent.call(this)
}
let child1 = new Child()
console.log(child1.name) // 输出 parent
console.log(child1.family) // 输出 undefined,拿不到父类原型上的方法
原型链继承
优点:可以继承父类的原型
缺点:父类引用值在子类实例实现了共用
Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
this.name = "parent"
this.arr2 = [11]
}
function Child() {
this.name = "Child"
this.arr3 = [111]
}
Child.prototype = new Parent()
let child1 = new Child()
let child2 = new Child()
console.log(child1.arr1) // [1]
console.log(child1.arr2) // [11]
console.log(child1.arr3) // [111]
child1.arr2.push(22)
console.log(child2.arr2) // [11, 22]
child1.family = "洛家"
console.log(child1.family) // "洛家"
console.log(child2.family) // "罗斯柴尔德家族"
构造函数 + 原型链 继承
优点:解决父类引用值共用问题
缺点:子类实例化的时候,父类构造函数被执行了两次
Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
this.name = "parent"
this.arr2 = [11]
}
function Child() {
Parent.call(this)
this.name = "Child"
this.arr3 = [111]
}
Child.prototype = new Parent()
let child1 = new Child()
let child2 = new Child()
console.log(child1.arr1) // [1]
console.log(child1.arr2) // [11]
console.log(child1.arr3) // [111]
child1.arr2.push(22)
console.log(child2.arr2) // [11]
child1.family = "洛家"
console.log(child1.family) // "洛家"
console.log(child2.family) // "罗斯柴尔德家族"
构造函数 + 原型链 继承优化1
优点:子类实例化,父类被构造两次的问题
缺点:子类实例化后,构造函数变为Parent
Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
this.name = "parent"
this.arr2 = [11]
}
function Child() {
Parent.call(this)
this.name = "Child"
this.arr3 = [111]
}
Child.prototype = Parent.prototype
let child1 = new Child()
console.log(child1.__proto__.constructor == Parent) // true
构造函数 + 原型链 继承优化2 完美继承
优点:完美继承
Parent.call(this)
Child.prototype = Object.prototype(Parent.prototype)
Child.prototype.constructor = Child
Parent.prototype.family = "罗斯柴尔德家族"
Parent.prototype.arr1 = [1]
function Parent() {
this.name = "parent"
this.arr2 = [11]
}
function Child() {
Parent.call(this)
this.name = "Child"
this.arr3 = [111]
}
Child.prototype = Object.create(Parent.prototype)
Child.prototype.constructor = Child
let child1 = new Child()
console.log(child1.__proto__.constructor == Parent) // false
console.log(child1.__proto__.constructor == Child) // true
圣杯模式
var inherit = (function (){
var F = function() {}
return function(Target, Origin) {
F.prototype = Origin.prototype
Target.prototype = new F()
Target.prototype.constructor = Target
// uber表示对象的最终原型来自于谁
Target.prototype.uber = Origin.prototype
}
})()