1.原型链继承
- 这种继承方式是通过让子类的原型对象指向父类的实例,从而让子类可以继承父类原型链上的所有属性和方法。
- 优点:简单易用,可以实现多重继承。
- 缺点:无法向父类构造函数传递参数,所有子类实例共享父类实例的属性,修改一个子类实例的属性可能会影响其他子类实例。
- 应用场景:适用于不需要传递参数,且不关心原型属性是否被修改的情况。
2.构造函数继承
- 这种继承方式是通过在子类构造函数中调用父类构造函数,从而让子类可以继承父类的实例属性和方法。
- 优点:可以向父类构造函数传递参数,可以实现多个子类共享同一个父类实例,子类修改实例属性不会影响其他子类。
- 缺点:无法继承父类原型对象的属性和方法,每个子类都要重新创建父类的实例属性和方法,造成资源浪费。
- 应用场景:适用于需要传递参数,且关心实例属性是否被修改的情况。
3.组合继承
- 通过结合原型链继承和构造函数继承,实现子类对父类属性和方法的完全继承。
- 优点:可以向父类传递参数,可以复用父类原型的方法,避免了引用类型属性共享的问题,是最常用的继承方式。
- 缺点:调用了两次父类构造函数,生成了两份父类属性,存在内存浪费的问题。
- 应用场景:适合大部分的继承需求,不需要考虑内存优化的情况。
4.原型式继承
- 这种继承方式是通过一个函数来创建一个临时的构造函数,然后让这个临时的构造函数的原型对象指向一个目标对象,从而让这个临时的构造函数的实例可以继承目标对象的属性和方法。
- 优点:简单易用,可以实现对任意对象的浅拷贝。
- 缺点:无法向构造函数传递参数,无法实现多个子类共享同一个父类实例,子类修改原型属性会影响其他子类。
- 应用场景:适用于不需要传递参数,且不关心原型属性是否被修改的情况。
5.寄生式继承
- 在原型式继承的基础上,在函数内部为对象绑定属性和方法,返回一个新对象。
- 优点:可以对继承的对象进行扩展,增加新的属性或方法。
- 缺点:跟构造函数继承一样,每次创建实例都要创建一遍方法,无法复用,效率较低。
- 应用场景:适合对一个对象进行浅复制或者克隆,并且需要增加一些新的功能。
- 代码案例:
6.寄生组合式继承
-
通过借用构造函数继承父类属性,通过寄生式继承父类原型:
- 通过构造函数方法来继承父类的属性;
- 通过寄生式继承父类原型,获取到父类的原型对象,通过寄生式方式创建一个中间对象,中间对象的原型为父类的原型对象,然后将中间对象作为子类的原型对象。这样可以避免父类子类共用一个原型对象,进而避免子类修改原型对象对父类的原型对象造成影响。
-
优点:集合了构造函数继承和寄生式继承的优点,是最完美的继承方式,也是ES6中class语法糖的实现原理。同时避免了调用两次父类构造函数的问题。
-
缺点:实现较为复杂,需要理解原型链和构造函数的关系。
-
应用场景:适合任何继承需求,需要考虑内存优化的情况。
7. class extends
使用的是组合继承式,通过super方法,来实现对于父类属性的继承,同时extends会将子类原型对象的原型指向父类的原型对象。实现对于父类原型上属性和方法的继承。
JavaScript中class extends的继承原理是基于原型链的,它实现了两个方面的继承:
- 子类的__proto__属性,表示构造函数的继承,总是指向父类。这样子类就可以使用父类的静态方法和属性。【对于子类本身而言,可以继承父类自身的属性和方法】
- 子类prototype属性的__proto__属性,表示方法的继承,总是指向父类的prototype属性。这样子类的实例就可以使用父类的原型方法和属性。
具体来说,当我们使用class A extends B语法时,JavaScript会做以下几个步骤:
- 创建一个子类A的构造函数,并将其__proto__属性指向父类B。这相当于Object.setPrototypeOf(A, B)。
- 创建一个子类A的原型对象,并将其__proto__属性指向父类B的原型对象。这相当于A.prototype = Object.create(B.prototype, {constructor: {value: A}})。
- 在子类A的构造函数中,调用super()函数,相当于B.call(this, …),将父类B的实例属性和方法复制到子类A的实例上。
- 在子类A的原型对象中,定义自己的方法和属性。
你可以参考以下网页来了解更多细节:
以上内容参考了以下网页:
1: JavaScript深入之继承的多种方式和优缺点 - 知乎 2: 6种JavaScript继承方式及优缺点 - 知乎 - 知乎专栏 3: JavaScript的六大继承方式及其优缺点 - 知乎 - 知乎专栏 4: js(javascript)实现继承的6种方式以及优缺点详解借用构造函数继承的缺点程序牛0314的博客-CSDN博客