1.普通继承
function Parent(name){
this.name = name
}
function Son(age,name) {
//!在父构造函数中给子类实例添加属性
this.age =age
}
Son.prototype= new Parent("bang")
Son.prototype.constructor = Son//使得parent的实例像一个原型空间
let s1 = new Son(1,'bang')
缺点 无法传给父类的name属性
2.prototype继承
function Parent(name){
this.name = name
}
function Son(age,name) {
//!在父构造函数中给子类实例添加属性
this.age =age
}
Son.prototype= Parent.prototype
Son.prototype.constructor = Son//使得parent的实例像一个原型空间
let s1 = new Son(1,'bang')
缺点
无法传给父类的name属性
无法读取parent的私有属性 只能读取原型对象属性
3.构造函数+修改protytpe
function Parent(name){
this.name = name
}
function Son(age,name) {
//!在父构造函数中给子类实例添加属性
Parent.call(this,name) //扩展s1这个对象上的属性 本来只有age一个属性 现在多一个name属性
this.age =age
}
Son.prototype= new Parent("bang") //这一次完全没必要
Son.prototype.constructor = Son//使得parent的实例像一个原型空间
let s1 = new Son(1,'bang')
可以实现读取parent的私有属性但是调用啦两次parant函数 第一次完全没必要
4.构造函数+修改protytpe
function Parent(name){
this.name = name
}
function Son(age,name) {
//!在父构造函数中给子类实例添加属性
Parent.call(this,name) //扩展s1这个对象上的属性 本来只有age一个属性 现在多一个name属性
this.age =age
}
Son.prototype= Parent.prototype
Son.prototype.constructor = Son//使得parent的实例像一个原型空间
let s1 = new Son(1,'bang')
缺点 Son.prototype.constructor = Son 这一个会让parent的 parent.prototype.constructor也为son不符合逻辑
5.寄生组合
采用中间函数的形式
function Parent(name){
this.name = name
}
function Son(age,name) {
//!在父构造函数中给子类实例添加属性
Parent.call(this,name) //扩展s1这个对象上的属性 本来只有age一个属性 现在多一个name属性
this.age =age
}
function _extends(parent,son){
function middle(){
this.constructor = son //this就是middle实例就是son.prototype
}
middle.prototype = parent.prototype
return new middle()
}
Son.prototype=_extends(Parent,Son)
let s1 = new Son(1,'bang')
console.log(s1)
主要是加一个Miiddle层解决Son.prototype= Parent.prototype导致修改Son.prototype.constructor = Son 时候 parent.prototype.constructor也为son的问题 加一层这个middle的实例的constructor 就指向Son,parent的不变 ,只是原型链长啦一节
_extends写法很麻烦,es6提供了object.create()函数
function Parent(name){
this.name = name
}
Parent.prototype.cname = 'parent的protytpe'
function Son(age,name) {
//!在父构造函数中给子类实例添加属性
Parent.call(this,name) //扩展s1这个对象上的属性 本来只有age一个属性 现在多一个name属性
this.age =age
}
function _extends(parent,son){
function middle(){
this.constructor = son //this就是middle实例就是son.prototype
}
middle.prototype = parent.prototype
return new middle()
}
Son.prototype= Object.create(Parent.prototype)
Son.prototype.constructor = Son
//Son.prototype=_extends(Parent,Son)
let s1 = new Son(1,'bang')
console.log(s1)
object.create()就是创建一个空函数然后把他的prototype=父函数的prototype,然后返回实例 和extends区别就是没有绑定constructor 让middle实例看上去更像一个原型对象空间
\