new.target 可在构造函数中精准识别实际被 new 的最底层子类,用于实现无侵入的智能依赖装配:基类通过 new.target 查依赖映射、调用容器解析并注入,支持匿名类、装饰器声明及高级 di 特性。

new.target 可以在构造函数中识别实际被 new 的类(而非直接调用的父类),这为“智能工厂”提供了关键线索:无需显式传入类型,就能自动判断子类身份,进而按需装配其专属依赖。
利用 new.target 动态识别子类类型
在基类构造函数中访问 new.target,它指向当前实例化时使用的**最底层类**。即使通过继承链调用,new.target 也不会是基类本身,而是具体子类(如 new UserService() 中 new.target === UserService)。
注意:new.target 在普通函数调用(非 new)时为 undefined,可借此防止非法调用。
基于子类名/元数据自动匹配依赖配置
预先定义一个依赖映射表,键为子类构造函数(或其 name),值为该子类所需的依赖项(如实例、工厂函数或配置对象):
- 直接用
new.target作 Map 键,最精确(支持匿名类、避免 name 冲突) - 若需声明式配置,可在子类上静态定义
dependencies属性,基类读取new.target.dependencies - 配合 TypeScript 装饰器,可将依赖声明写在类上方,运行时注入到
new.target上
在基类构造中完成自动装配
基类构造函数不硬编码任何具体依赖,而是:
- 检查
new.target是否存在且不等于基类自身(防误用) - 查表获取该子类对应的依赖描述(例如 { db: UserDb, logger: ApiLogger })
- 依次实例化或从容器获取依赖,并挂载到
this上(如this.db = container.get(dbType)) - 可预留钩子(如
new.target.beforeInject?.(this))供子类干预装配过程
配合依赖注入容器提升灵活性
单纯靠 new.target 只能识别“要什么”,真正“给什么”应交给容器处理:
- 将依赖注册进容器时,同时绑定到对应子类(如
container.bind(UserService).toSelf().withDependencies(...)) - 基类中调用
container.resolve(new.target),容器内部根据new.target查依赖元数据并递归解析 - 这样既保持构造函数简洁,又支持单例、作用域、异步初始化等高级特性
不复杂但容易忽略:new.target 是唯一能在构造函数内无侵入感知“谁在实例化我”的原生机制,把它和依赖声明解耦开,工厂逻辑就自然浮现了。











