如何实现继承(原型和原型链)

一、原型链继承

1. 基本原理
  • 利用原型对象的特性,让一个构造函数的原型对象等于另一个构造函数的实例,这样一来,基于该原型对象的所有实例就能访问到被继承的构造函数原型上的属性和方法,从而实现继承效果。通过这种方式形成了一条原型链,沿着这条链可以向上查找属性和方法。
2. 代码示例
3. 优缺点
  • 优点:实现方式相对简单直观,能够实现属性和方法的继承,基于原型链可以共享原型上的方法,节省内存空间(多个实例共享同一个原型上的方法)。
  • 缺点
  • 所有实例共享父类实例属性(因为是通过父类实例来构建原型链的),如果一个实例修改了从父类实例继承来的属性,会影响到其他实例。例如:

二、构造函数继承(借助 call 或 apply)

1. 基本原理
  • 通过在子类构造函数中使用callapply方法来调用父类构造函数,并将子类构造函数中的this绑定,使得父类构造函数中的属性能够被添加到子类实例上,实现属性的继承,不过这种方式没有继承父类原型上的方法,需要单独处理。
    3. 优缺点
  • 优点
    • 解决了原型链继承中实例共享父类实例属性的问题,每个子类实例都有自己独立的父类属性副本,相互之间不会干扰。
    • 可以在子类构造函数调用父类构造函数时传递参数,更具灵活性。
  • 缺点
    • 没有继承父类原型上的方法,需要手动在子类中重新定义或者通过其他方式(如将父类原型上的方法复制过来等)添加,比较繁琐。
    • 每个子类实例都会创建父类构造函数中方法的副本(比如上面示例中的play方法),无法实现方法的复用,浪费内存空间(相比于原型链继承在方法复用方面的优势)。

三、组合继承(原型链继承 + 构造函数继承)

1. 基本原理
  • 结合了原型链继承和构造函数继承的优点,先通过构造函数继承的方式让子类实例拥有父类的属性,保证每个实例属性独立,再通过原型链继承的方式让子类实例继承父类原型上的方法,实现方法的复用,是一种比较常用且综合性能较好的继承方式。
2. 代码示例
3. 优缺点
  • 优点
    • 综合了原型链继承和构造函数继承的优点,既解决了实例属性共享问题,又实现了原型方法的复用,是一种相对较为完善的继承实现方式。
    • 可以向父类构造函数传递参数,灵活性较好。
  • 缺点
    • 调用了两次父类构造函数(一次是在设置子类原型时通过new Parent(),一次是在子类构造函数中通过call调用),一定程度上影响了性能,不过在大多数场景下这个性能影响可以接受。

四、寄生组合继承(优化后的组合继承)

1. 基本原理
  • 针对组合继承中调用两次父类构造函数的问题进行优化,不再通过new Parent()的方式来设置子类原型,而是创建一个中间对象,让这个中间对象的原型指向父类原型,然后将子类原型指向这个中间对象,这样就避免了不必要的父类构造函数调用,同时保留了组合继承的优点。
2. 代码示例
3. 优缺点
  • 优点
    • 解决了组合继承中调用两次父类构造函数的问题,优化了性能,同时继承了父类的属性和原型上的方法,保持了实例属性独立和方法复用的优点,是一种比较理想的继承实现方式。
    • 可以向父类构造函数传递参数,灵活性好。
  • 缺点
    • 实现代码相对其他简单继承方式略显复杂,不过理解后代码逻辑还是比较清晰的。

五、ES6 类继承(基于 class 和 extends)

1. 基本原理
  • ES6 引入了class语法糖,本质上还是基于原型和原型链来实现继承,但语法更加简洁清晰,通过extends关键字表明继承关系,在子类构造函数中使用super关键字来调用父类构造函数,实现属性继承,并自动继承父类原型上的方法。
2. 代码示例
3. 优缺点
  • 优点
    • 语法简洁明了,易于理解和书写,遵循了面向对象编程中类继承的常见语法形式,降低了学习成本,尤其是对于熟悉其他面向对象语言的开发者来说。
    • 底层依然基于原型和原型链实现了高效的继承机制,自动处理了很多继承相关的细节,如原型链的构建、super的正确调用等。
  • 缺点
    • 只是语法糖,本质还是原型和原型链相关机制,对于不深入理解原型和原型链的开发者来说,可能在遇到一些复杂继承问题(比如涉及到原型链深层次的属性查找等)时难以准确调试和解决问题,因为可能只是表面上熟悉class相关语法,而没有真正掌握其背后的原理。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值