es5中JavaScript的6种继承方法
继承方法:原型链、借用构造函数、组合继承、原型式继承、寄生式继承和寄生组合式继承。
1⃣️.原型链
特点:实例可继承的属性有:实例的构造函数的属性+父类构造函数属性+父类prototype的属性。
缺点:新实例无法向父类构造函数传参|单一继承|所有新实例都会共享父类prototype上的属性。
function Father(){
this.name = 'daddy'
}
Father.prototype.say = function(){
console.log('i am father')
}
function Son(){}
//这里既有父类prototype的内容&&父类构造函数中的内容
Son.prototype = new Father()
2⃣️.借用构造函数继承
特点:解决原型链的缺点
缺点:只能继承父类构造函数属性|无法实现构造函数的复用|每个新实例里面都要call和apply一下,代码臃肿
function Father(name){
this.name = name
}
function Son(){
Father.call(this,'daddy')
}
3⃣️.组合继承
特点:结合原型链和借用构造函数的优点
缺点:需要调用两次父类构造函数(耗内存),会在实例对象上挂载一次构造器中的属性,在原型对象上也挂载一次原型对象的属性
function Father(name){
this.name = name
}
Father.prototype.say = function(){
console.log('i am daddy')
}
function Son(name,age){
Father.call(this,name) //第二次调用父类的构造函数
this.age = age
}
Son.prototype = new Father() //第一次调用父类的构造函数
4⃣️.原型式继承(类似于Object.create方法)
特点:可以通过实例对象来创建克隆实例(主要关注实例对象)
缺点:无法复用,prototype共享
function object(o){
function F(){}
F.prototype = o
return new F()
}
5⃣️.寄生式继承
特点:创建一个实现继承的函数,以某种方式增强对象(同主要关注实例对象)
function object(o){
function F(){}
F.prototype = o
return new F()
}
function createAnother(original){
let clone = object(original) //可以换成其他的返回新对象的函数
clone.newFun = function(){
console.log('新增的功能')
}
return clone
}
6⃣️.寄生组合式继承
特点:解决了组合式继承中需要调用两次构造函数的缺点
function inheritPrototype(son,father){
let prototype = object(father.prototype) //相比于new father,不会再次调用父类的构造函数,通过父类的克隆原型对象当成子类的原型对象
prototype.constructor = son
son.prototype = prototype
}
function father(name){
this.name = this.name
}
father.prototype.say = function(){
console.log('i am daddy')
}
function son(name){
father.call(this,name) //调用父类的构造函数
this.age = 18
}
inheritPrototype(son,father)