刷刷题46(常见的三种js继承类型及其优缺点)

一、原型链继承

原理

通过将 ‌子类构造函数的原型(prototype ‌ 指向 ‌父类实例‌,实现继承链。

示例

javascript 复制代码
// 父类
function Animal(name) {
  this.name = name || 'Animal';
  this.colors = ['black', 'white'];
}
Animal.prototype.say = function() {
  console.log(`I'm ${this.name}`);
};

// 子类
function Cat() {}
Cat.prototype = new Animal(); // 原型链继承

// 测试
const cat1 = new Cat();
cat1.say(); // I'm Animal(继承父类方法)
cat1.colors.push('orange');
console.log(cat1.colors); // ['black', 'white', 'orange']

const cat2 = new Cat();
console.log(cat2.colors); // ['black', 'white', 'orange'](引用类型属性被共享!)

特点

  • 优点‌:简单易实现,可继承父类实例属性及原型方法。

  • 缺点‌:

    • 所有子类实例共享父类实例的 ‌引用类型属性 ‌(如 colors 数组)。
    • 无法向父类构造函数传递参数(如 name 参数在子类中无法自定义)。

二、构造函数继承(借用构造函数)

原理

在子类构造函数中通过 callapply 调用父类构造函数,继承父类实例属性。

示例

javascript 复制代码
// 父类
function Animal(name) {
  this.name = name || 'Animal';
  this.colors = ['black', 'white'];
}
Animal.prototype.say = function() {
  console.log(`I'm ${this.name}`);
};

// 子类
function Cat(name) {
  Animal.call(this, name); // 构造函数继承(可传参)
}

// 测试
const cat1 = new Cat('Tom');
cat1.colors.push('orange');
console.log(cat1.colors); // ['black', 'white', 'orange']
console.log(cat1.name); // Tom(参数传递成功)

const cat2 = new Cat('Jerry');
console.log(cat2.colors); // ['black', 'white'](引用类型属性独立!)

cat1.say(); // TypeError: cat1.say is not a function(无法继承父类原型方法!)

特点

  • 优点‌:

    • 解决引用类型属性共享问题。
    • 支持向父类构造函数传递参数。
  • 缺点 ‌:无法继承父类原型上的方法(如 say 方法)。


三、ES6 Class 类继承

原理

通过 extendssuper 关键字实现继承,底层基于 ‌寄生组合继承‌,语法更简洁。

示例

javascript 复制代码
// 父类
class Animal {
  constructor(name) {
    this.name = name || 'Animal';
    this.colors = ['black', 'white'];
  }
  say() {
    console.log(`I'm ${this.name}`);
  }
}

// 子类
class Cat extends Animal {
  constructor(name) {
    super(name); // 调用父类构造函数
    this.age = 2;
  }
  // 可扩展子类方法
  meow() {
    console.log('Meow!');
  }
}

// 测试
const cat1 = new Cat('Tom');
cat1.say(); // I'm Tom(继承父类方法)
cat1.colors.push('orange');
console.log(cat1.colors); // ['black', 'white', 'orange']

const cat2 = new Cat('Jerry');
console.log(cat2.colors); // ['black', 'white'](引用类型属性独立!)
cat2.meow(); // Meow!(子类自定义方法)

特点

  • 优点‌:

    • 语法简洁,完全面向对象。
    • 解决引用类型共享问题,支持传参。
    • 自动继承父类原型方法。
  • 底层实现 ‌:
    class 继承本质上是通过 ‌寄生组合继承‌ 实现,避免构造函数重复调用,性能最优。

四、对比总结

继承方式 核心原理 优点 缺点
原型链继承 子类原型指向父类实例 简单,可继承父类原型方法 引用类型属性共享,无法传参
构造函数继承 子类构造函数中调用父类构造函数 解决属性共享问题,支持传参 无法继承父类原型方法
ES6 Class 继承 基于 extendssuper 的语法糖 语法简洁,解决所有继承问题,性能最优 需支持 ES6 环境
相关推荐
神探小白牙15 分钟前
eCharts 多系列柱状图增加背景图
javascript·ecmascript·echarts
女生也可以敲代码20 分钟前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
ZhengEnCi27 分钟前
M5-markconv自定义CSS样式指南 📝
前端·css·python
IT_陈寒1 小时前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
xingpanvip1 小时前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua
@PHARAOH1 小时前
WHAT - GitLens supercharged 插件
前端
TT模板1 小时前
苹果cms整合西瓜播放器XGplayer插件支持跳过片头尾
前端·html5
Wect2 小时前
React 性能优化精讲
前端·react.js·性能优化
Cosolar2 小时前
告别无脑循环:深入解析 ReWOO 与 Plan-and-Execute Agent 架构
人工智能·面试·全栈
追风筝的人er2 小时前
SpringBoot+Vue3 企业考勤如何处理法定假期?节假日方案、调休补班与工作日判断链路拆解
前端·vue.js·后端