js面试重点总结(继承)
继承是什么
继承是子类可以使用父类的属性和方法,并且可以自己添加新的属性和方法或者重写覆盖原有属性方法,js不是真正面向对象的语言,但是由于其很灵活,可以使应用场景更丰富
继承的几种方式
- 原型链继承
使子类的prototype指向一个新的new父类的实例对象,通过该方法使子类能够通过原型链调用到父类prototype上挂载的方法,该方法不再是仅仅将子类的prototype直接指向父类的prototype,使父类子类公用同一个原型对象,因此指向一个新的父类实例对象就避免子类修改prototype中的方法而父类中的也同时发生改变的问题。该继承方式仅能继承父类原型对象中的方法但是也有潜在问题:
- 原型属性中若包含引用数据类型则所有的子类中修改该引用数据类型的属性,其他子类也会发生改变,因为他们均共享了同一块内存空间
- 创建子类时无法传参
- 借用构造函数继承
在子类构造函数中用call/apply调用父类构造函数的同时修改this指向指向子类自身 该方法解决了原型链继承时产生的引用数据类型共用的问题但是却只能继承父类自身的实例属性和方法,不能继承父类原型方法和属性
- 组合式继承
就是融合了上述1+2两种继承方式的一种继承方式
- 寄生组合式继承
当我们使用原型链继承方式去继承父类原型上的方法时利用的是new一个新的父类实例对象的方法,但是其中父类自带的构造函数属性是多余的,仍然会以空值的方式存在其中,并且我们发现在使用组合式继承时,我们调用了两次父构造函数,造成了多调用一次父构造函数的性能开销,因此我们可以使用Object.create方法来构造一个空的对象,该方法后面的参数会作为新构造的空实例对象的__proto__,那我们就可以让Son.prototype=Object.create(Father.prototype的方式)再加上借用构造函数继承,这样既解决了属性继承也解决了原型对象内的方法继承,目前该方法是继承的相对最优解
- es6类继承 利用extends关键字和super关键字直接实现继承,实际上也是寄生组合式继承,因此也可以说明目前是相对最优解