js继承的六种方式

继承方式:

原型链继承

借用构造函数继承

组合继承

原型式继承

寄生式继承

寄生组合式继承

  • 原型式继承

缺点: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.避免子类 示例共享引用属性的情况

  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);

个人笔记,如有错漏之处,敬请指正

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值