You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript类私有属性在受保护函数中未定义的问题与最佳实践咨询

TypeScript类继承中构造函数调用子类方法导致属性未初始化的解决方案

你猜的没错,问题确实出在类的初始化顺序上:

  1. 创建AppRoute实例时,首先执行父类RouteBase的构造函数
  2. 父类构造里调用了init(),进而触发registerRoute()——但此时子类AppRoute的apiRoute属性还没完成初始化(子类实例属性是在父类构造执行完毕后才赋值的)
  3. 因此this.apiRoute为undefined,自然无法读取router属性

下面是几种可行的最佳实践:

方案1:分离初始化逻辑,子类主动触发

修改父类RouteBase,移除构造函数中的自动初始化逻辑,让子类在super()之后手动调用init(),确保子类属性已经初始化完成:

// route.base.ts
export abstract class RouteBase {
  public router = Router()

  constructor() {} // 不再自动执行初始化

  public init(): void {
    this.registerRoute()
  }

  protected abstract registerRoute(): void
}

子类构造函数中,在super()后调用init():

// app.routing.ts
export class AppRoute extends RouteBase {
  private apiRoute = new ApiRoute()

  constructor() {
    super()
    // 此时apiRoute已完成初始化,再执行路由注册
    this.init()
  }

  protected registerRoute(): void {
    this.router.use('/api', this.apiRoute.router)
  }
}
// api.routing.ts
export class ApiRoute extends RouteBase {
  constructor() {
    super()
    this.init()
  }

  protected registerRoute(): void {
    this.router.get('/test', (req, res, next) => res.send('api test.'))
  }
}

使用时正常创建实例即可:

const appRoute = new AppRoute()

方案2:用静态工厂方法创建实例

如果不想手动调用init(),可以给父类添加静态工厂方法,确保实例属性初始化完成后再执行注册逻辑:

// route.base.ts
export abstract class RouteBase {
  public router = Router()

  protected constructor() {} // 保护构造,强制通过静态方法创建实例

  public init(): void {
    this.registerRoute()
  }

  protected abstract registerRoute(): void

  // 静态工厂:先创建实例(完成属性初始化),再执行初始化
  public static create<T extends RouteBase>(this: new () => T): T {
    const instance = new this()
    instance.init()
    return instance
  }
}

子类无需修改构造函数,直接通过静态方法创建实例:

const appRoute = AppRoute.create()
const apiRoute = ApiRoute.create()

核心原则

永远不要在父类构造函数中调用会被子类重写的方法——这是面向对象编程的常见陷阱,此时子类的实例成员还未完成初始化,极易引发未定义错误。将初始化逻辑延迟到子类构造之后,或通过工厂方法确保实例完全创建后再执行,是更安全的做法。

内容的提问来源于stack exchange,提问作者Andoma Chen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 03:40:20