JS继承的实现
JS继承的实现
JS中的继承方式多种,具体分类如下
继承方式1:拷贝继承
(1)子类构造函数中创建父类对象
(2)把父类对象所有属性拷贝到子类构造函数原型中
(3)给子类添加自己的属性和方法
缺点:
子类所有对象的原型(父类对象)共享,如果修改任何一个对象的父类引用内容,所有对象会同步
效率低、占用内存大,创建一个子类对象同时,需要创建一个父类对象
无法继承父类不可枚举的属性和方法
继承方式2:原型链(prototype chaining)
原理:把父类的对象作为子类的原型
优点:
编写简单、容易理解
父类的属性和原型属性子类都能访问
缺点:
子类所有对象的原型(父类对象)共享,如果修改任何一个对象的父类引用内容,所有对象会同步
创建子类实例时候,没有办法对父类构造方法内部初始化属性
继承方式3:构造函数继承
原理:相当于复制父类的实例属性给子类
在子类构造函数中,通过call方法调用父类构造函数
在调用父类构造函数时候,同时初始化了子类构造函数属性
优点:
解决了父类原型数据共相问题,并可以初始化参数
可以实现多重继承
缺点:
实例跟父类没关系,脱离了继承的本质
只能继承父类实例属性和方法,不能继承原型属性和方法
继承方式4:混合方式继承(原型链+构造方法)
在子类构造函数中,通过call方法调用父类构造函数
子类的原型指向父类对象实例
优点:
可以继承父类示例属性和方法,也能继承原型属性和方法
既是子类实例也是父类实例
缺点:
调用了2次父类构造方法,增大了开销
继承方式5:混合桥接式继承(推荐使用)
在子类构造函数中,通过call方法调用父类构造函数,引入所有属性
定义一个空的对象,作为桥接
子类原型指向空的对象,空的对象原型指向父类原型
优点:
只定义了一个空对象,极大的减少了开销
缺点:
还是有多余的开销