继承方式:
原型链继承
借用构造函数继承
组合继承
原型式继承
寄生式继承
寄生组合式继承
- 原型式继承
缺点:Parent中引用属性会被每一子类实例共享
//原型链继承
function Parent(){
this.parentPrototype=”parent prototype”
//验证这个继承方法的确定,如果父类中存在一个引用类型的属性,会被所有的子类共享
this.parentObj={
info:”我是父类中的parentObj.info”}
}
function Children(){
}
//将children的原型对象指向为parent的示例,通过原型链,就可以将parent中的属性赋值给children
Children.prototype=new Parent();
const a=new Children();
console.log(a.parentPrototype);//parent prototype
//缺点
const b=new Children();
//就是在a子级中修改继承得到的引用属性会被b示例共享
a.parentObj.info=’我是a实例中的parentObj.info’;
console.log(b.parentObj.info);//我是a实例中的parentObj.info
- 借用构造函数继承
优点:1.避免子类 示例共享引用属性的情况
- 可以在实例化的时候给Parent构造函数传递参数
缺点:如果Parent中存在一个函数,那每次实例化Children就会创造一个同样函数,不利于函数复用。
function Parent(){
this.parentPrototype=”parent prototype”
this.obj={
info:”parent obj info”}
this.fn=function(){
console.log(“打印功能”)
}
}
function Children(){
Parent.call(this);
}
const a=new Children();
console.log(a.parentPrototype);//parent prototype
//缺点就是在Parent()被Children继承后贵再次创建一个fn函数,这个是没有必要的
a.obj.info=”a obj info”
console.log(b.obj.info)//parent obj info
- 组合继承:原型链+构造函数(这个是js中最常见的继承方式)
优点:避免子类共享父类的引用属性同时避免了父类构造函数重复对function属性创建
function Parent(){
this.parentPrototype=’我是parent中的属性’;}
//parent中的方法,在原型上定义
Parent.prototype.pFn=function(){
console.log(‘我是Parent中的方法’);
}
function Children(){
//Parent中属性仍然在构造函数中继承
Parent.call(this);
}
//将Children的原型对象为Parent实例,这样Parent中的方法也能被Children继承
Children.prototype=new Parent();
const c=new Children();
console.log(c.parentPrototype);//我是Parent中的属性
c.pFn();//我是Parent中的方法
- 原型式继承(原型式继承不是原型链,并使用较少)
缺点:和原型链一样,后代实例会共享父类引用属性
function objFn(o)
{
o.objFnPrototype=”我是 objFnPrototype”
function Fn(){
F.prototype=o;
}
return new F();
}
let a=objFn({
name:’name1’;
});
console.log(a.name);//name1
console.log(a.objFnPrototype);//我是objFnPrototype
- 寄生式继承(定义一个方法,复制一个对象,然后在复制的对象身上添加属性和方法,然后return)
缺点:和原型链一样,后代实例会共享父类引用属性
function createObje(obj)
{
let clone=Object.assign(pbj);//接受到对象后,原封不动的创建一个新对象
clone.prototype1=”我是新增的prototype1”;//在新对象上添加属性,就是所谓的寄生
return clone;//返回新对象
}
const parent={
parentPrototype:”parentPrototype”
}
//c实例 就继承了parent所有属性
let c=createObje(parent);
console.log(c.parentPrototype);//parentPrototype
- 寄生组合继承(寄生+组合(原型链+借用构造函数))
优点:和组合继承一样,但是组合继承没有调用两次父类构造函数的缺点
function inherProto(superType,subType)
{
//高倍一个超类的原型副本
let proto={
...superType.prototype
};
//将原型的超类副本作为子类的原型对象,也就是第一种原型链的继承法是,只不过继承的是超类原型
subType.prototype=proto;
proto.constructor=subType;
}
function Super(){
this.superProto=’super proto’;
this.colors=[‘red’,’yellow’];
}
function Sub(){
this.subProto=”sub proto”
this.name=’sub name’
Super.call(this);
}
Super.prototype.getName=function(){
console.log(this.name);
}
inherProto(Super,Sub);
let a=new Sub();
console.log(a.getName);