TypeScript 继承实现:不使用 extends、Object.assign 或 Object.setPrototypeOf

在 TypeScript 中,我们可以使用 extends 关键字来实现继承。然而,有时我们可能需要在不使用 extendsObject.assignObject.setPrototypeOf 的情况下,实现继承并保留子类自身的方法。

例如,假设我们有两个类:ParentChildChild 需要继承 Parent 的方法,同时还拥有自己的方法 methodC

传统方法:

class Parent {
  constructor() {}
  public methodA() {}
  public methodB() {}
}

const parent = new Parent();

class Child {
  constructor() {
    Object.assign(Child.prototype, Object.getPrototypeOf(parent));
  }
  public methodC() {}
}

const child = new Child()
child.methodA()
child.methodB()
child.methodC()

问题:

  • Object.assign 无法合并 prototype,导致 methodC 丢失。
  • Object.setPrototypeOf 会修改自身原型对象 prototype,导致 methodC 丢失。

解决方案:

我们可以使用原型链的方式实现继承,并保留 methodC。具体步骤如下:

  1. Child 的原型对象设置为 Parent 的实例。
  2. methodC 添加到 Child 的原型对象上。

示例代码:

class Parent {
  constructor() {}
  public methodA() {}
  public methodB() {}
}

class Child {
  constructor() {
    // 将 Child 的原型对象设置为 Parent 的实例
    Child.prototype = new Parent();
    // 将 methodC 添加到 Child 的原型对象上
    Child.prototype.methodC = function() {};
  }
}

const child = new Child();
child.methodA();
child.methodB();
child.methodC();

解释:

  • 通过 Child.prototype = new Parent(),将 Child 的原型对象设置为 Parent 的实例,这样 Child 就继承了 Parent 的方法。
  • 通过 Child.prototype.methodC = function() {},将 methodC 添加到 Child 的原型对象上,这样 Child 就拥有了自己的方法。

通过这种方式,我们可以在不使用 extendsObject.assignObject.setPrototypeOf 的情况下,实现继承并保留子类自身的方法。

注意:

  • 使用原型链实现继承时,需要注意 constructor 的定义。因为 Childconstructor 会被覆盖,需要在 constructor 中手动调用父类的 constructor
  • 使用原型链实现继承可能会导致一些问题,例如:
    • 无法调用父类的静态方法。
    • super 关键字无法使用。
    • 可能会出现一些 unexpected behavior。

建议在实际开发中,尽可能使用 extends 关键字来实现继承。

总结:

本文介绍了在 TypeScript 中,不使用 extendsObject.assignObject.setPrototypeOf 的情况下,如何通过原型链实现继承,并保留子类自身的方法。这种方法虽然可行,但是建议在实际开发中尽可能使用 extends 关键字来实现继承。


原文地址: https://www.cveoy.top/t/topic/o0FS 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录