导读:本期聚焦于小伙伴创作的《JS Class继承中如何正确复写父类方法并修改入参:super关键字的正确用法》,敬请观看详情,探索知识的价值。以下视频、文章将为您系统阐述其核心内容与价值。如果您觉得《JS Class继承中如何正确复写父类方法并修改入参:super关键字的正确用法》有用,将其分享出去将是对创作者最好的鼓励。

JS中Class继承:如何正确复写父类方法并修改入参

在JavaScript的面向对象编程中,Class继承是非常常见的场景。当子类需要复用父类的逻辑,同时又要对父类的方法进行定制时,就涉及到父类方法的复写以及入参修改的问题。本文将详细介绍正确的实现方式,以及需要注意的边界情况。

基础回顾:Class继承的基本语法

ES6引入的Class语法本质是原型继承的语法糖,通过extends关键字可以实现子类对父类的继承,使用super关键字可以调用父类的构造函数或者方法。首先看一个基础的父类示例:

class Parent {
  constructor(name) {
    this.name = name;
  }

  // 父类的基础方法,接收两个参数并返回拼接结果
  greet(prefix, suffix) {
    return `${prefix}${this.name}${suffix}`;
  }
}

上述Parent类有一个greet方法,接收prefixsuffix两个入参,返回拼接后的字符串。

复写父类方法并修改入参的正确方式

当子类需要复写父类的greet方法,同时修改入参逻辑时,核心思路是:在子类方法中先处理自己的入参逻辑,再通过super.方法名()调用父类的同名方法,传入处理后的参数。以下是具体实现:

class Child extends Parent {
  constructor(name, age) {
    // 先调用父类构造函数,传入子类需要的参数
    super(name);
    this.age = age;
  }

  // 复写父类的greet方法,新增age参数,修改入参逻辑
  greet(prefix, suffix, showAge) {
    // 子类自己的入参处理逻辑:如果showAge为true,修改前缀加入年龄信息
    let newPrefix = prefix;
    if (showAge) {
      newPrefix = `${prefix}[${this.age}岁]`;
    }
    // 调用父类的greet方法,传入处理后的参数,也可以补充子类特有的参数处理
    const parentResult = super.greet(newPrefix, suffix);
    // 可以在父类返回结果的基础上做进一步处理
    return `${parentResult},欢迎来到https://www.ipipp.com`;
  }
}

上述代码中,Child类复写了greet方法,新增了showAge入参,先根据showAge的值修改了prefix参数,再通过super.greet调用父类方法传入处理后的参数,最后对返回结果做了补充。我们测试一下效果:

const parent = new Parent('张三');
console.log(parent.greet('你好,', '!')); 
// 输出:你好,张三!

const child = new Child('李四', 18);
console.log(child.greet('你好,', '!', true)); 
// 输出:你好,[18岁]李四!,欢迎来到https://www.ipipp.com
console.log(child.greet('你好,', '!', false)); 
// 输出:你好,李四!,欢迎来到https://www.ipipp.com

需要注意的关键问题

1. super的使用限制

在子类的构造函数中,必须先调用super()才能使用this,否则会抛出引用错误。而在子类的方法中,super.父类方法名()的调用没有顺序限制,只要是在子类方法的逻辑中合适的位置即可。

2. 入参的兼容性处理

如果子类复写方法时修改了入参的数量或者含义,建议尽量保持和父类方法的兼容,避免破坏原有的调用逻辑。比如如果父类方法支持两个参数,子类新增参数可以设置为可选参数,这样原有调用父类方法的代码在子类实例上也能正常运行:

class CompatibleChild extends Parent {
  greet(prefix, suffix, showAge = false) {
    // 即使不传showAge,也能正常调用,兼容父类的调用方式
    let newPrefix = prefix;
    if (showAge && this.age) {
      newPrefix = `${prefix}[${this.age}岁]`;
    }
    return super.greet(newPrefix, suffix);
  }
}

const compatibleChild = new CompatibleChild('王五', 20);
console.log(compatibleChild.greet('你好,', '!')); // 正常运行,输出:你好,王五!

3. 不要直接修改父类的原型方法

有些开发者可能会尝试直接修改Parent.prototype.greet来实现复写,这种方式会修改所有父类实例的行为,不符合继承的预期,也不利于代码的维护,因此不推荐使用。

复杂场景:修改入参并复用父类逻辑

如果父类的入参比较复杂,子类需要对其中的部分参数做转换后再传入,也可以先解析父类的入参结构,再构造新的参数传入。例如父类方法接收一个配置对象作为入参:

class ConfigParent {
  constructor(name) {
    this.name = name;
  }

  // 父类方法接收配置对象入参
  formatInfo(config) {
    const { prefix = '', suffix = '', upperCase = false } = config;
    let result = `${prefix}${this.name}${suffix}`;
    if (upperCase) {
      result = result.toUpperCase();
    }
    return result;
  }
}

class ConfigChild extends ConfigParent {
  // 复写方法,修改入参逻辑:新增timestamp参数,补充到prefix中
  formatInfo(config) {
    const { prefix = '', suffix = '', upperCase = false, addTimestamp = false } = config;
    let newPrefix = prefix;
    if (addTimestamp) {
      newPrefix = `${new Date().toLocaleDateString()}-${prefix}`;
    }
    // 构造新的配置对象传入父类方法
    return super.formatInfo({
      prefix: newPrefix,
      suffix,
      upperCase
    });
  }
}

const configChild = new ConfigChild('赵六');
console.log(configChild.formatInfo({
  prefix: '用户:',
  suffix: ',信息已同步',
  addTimestamp: true
}));
// 输出示例:2024/5/20-用户:赵六,信息已同步

这种场景下,子类先解构父类的入参配置,再根据自己的逻辑修改部分配置项,最后构造符合父类要求的参数传入,既复用了父类的逻辑,又实现了入参的定制修改。

总结

在JS的Class继承中复写父类方法并修改入参,核心步骤为:

  • 子类通过同名方法复写父类方法

  • 在子类方法中先处理自己的入参逻辑,得到符合父类要求的参数

  • 通过super.父类方法名(处理后的参数)调用父类方法,复用原有逻辑

  • 可根据需要对父类返回的结果做进一步处理,再返回最终值

同时注意入参的兼容性、super的使用规则,避免直接修改父类原型,就能规范地实现方法复写和入参修改的需求。

Class继承 方法复写 super用法 JavaScript面向对象 入参修改

免责声明:已尽一切努力确保本网站所含信息的准确性。网站部分内容来源于网络或由用户自行发表,内容观点不代表本站立场。本站是个人网站免费分享,内容仅供个人学习、研究或参考使用,如内容中引用了第三方作品,其版权归原作者所有。若内容触犯了您的权益,请联系我们进行处理。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。前端、网络、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握网站开发与运维所需的核心技术栈。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端逻辑,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。