如何在JavaScript/TypeScript中从父类获取子类?
实现指定父类的子类集合查询
核心思路
通过维护全局类注册表,在子类创建时自动完成与父类的关联,避开反射、装饰器这类你认为的反模式,最终实现类似Class.childClasses(ClassName)的调用方式。
代码实现
// 全局注册表,存储父类到子类集合的映射 const classRegistry = new Map(); class BaseClass { // 创建子类并自动注册到父类注册表 static createSubclass(classBody = {}) { const childClass = class extends this { ...classBody }; // 将子类注册到当前父类的集合中 if (!classRegistry.has(this)) { classRegistry.set(this, new Set()); } classRegistry.get(this).add(childClass); return childClass; } // 查询指定父类的所有子类(含递归子类) static childClasses(targetClass) { const target = targetClass || this; const result = []; // 递归收集所有层级的子类 function collectSubclasses(cls) { const subclasses = classRegistry.get(cls) || new Set(); for (const subclass of subclasses) { result.push(subclass); collectSubclasses(subclass); } } collectSubclasses(target); return result; } }
使用示例
// 创建顶层父类Animal(继承自BaseClass) const Animal = BaseClass.createSubclass({ constructor(name) { this.name = name; }, eat() { console.log(`${this.name} is eating`); } }); // 创建Animal的子类Dog和Cat const Dog = Animal.createSubclass({ bark() { console.log(`${this.name} barks: Woof!`); } }); const Cat = Animal.createSubclass({ meow() { console.log(`${this.name} meows: Meow!`); } }); // 创建Dog的子类Puppy const Puppy = Dog.createSubclass({ playFetch() { console.log(`${this.name} plays fetch`); } }); // 查询Animal的所有子类 console.log(BaseClass.childClasses(Animal)); // 输出:[Dog, Puppy, Cat] // 查询Dog的子类 console.log(BaseClass.childClasses(Dog)); // 输出:[Puppy] // 查询BaseClass的所有子类(含多层继承) console.log(BaseClass.childClasses()); // 输出:[Animal, Dog, Puppy, Cat]
注意事项
- 所有需要跟踪子类的类都需通过
createSubclass方法创建,确保自动注册到注册表中 - 支持递归查询子类的子类,返回的是类的构造函数引用而非实例
- 注册表仅存储类的引用,不会导致内存泄漏(除非保留对类的长期引用)
内容的提问来源于stack exchange,提问作者Malix
相关产品推荐
相关产品推荐

