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

TypeScript父类调用路由初始化方法时子类回调函数为undefined

问题原因

该问题由JavaScript/TypeScript的类实例初始化顺序导致,具体执行逻辑如下:

  • 实例化子类时,首先执行super()进入基类构造函数,此时只会初始化基类定义的实例属性,子类的实例属性还未开始初始化
  • 你的代码中getAllUsers、createAPost是用箭头函数语法定义的实例属性,并非挂载在原型链上的类方法,这类属性的初始化会在基类构造执行完成、回到子类构造逻辑后才会执行
  • 因此基类构造中调用initializeRoutes()时,两个路由处理函数还未被赋值,自然为undefined;等基类构造跑完、子类实例属性初始化完成后,子类构造中再调用initializeRoutes()就能正常获取到函数
解决方案

以下是3种可直接落地的改造方案:

方案1(改动最小):删除基类构造中的initializeRoutes调用

仅保留子类构造中super()执行完成后的调用即可,此时子类实例属性已经初始化完成:

// 基类Controller改造后代码
import express, {Router} from "express";

export abstract class Controller {
  public router = express.Router();
  public path: string;

  protected constructor(path: string) {
    this.path = path;
    // 移除原本的this.initializeRoutes()调用即可
  }
  abstract initializeRoutes(): void;
}

方案2:将路由处理函数改为原型方法,注册时绑定this

原型方法在类定义完成时就已挂载到原型链,基类构造执行期间也能正常访问,不会出现undefined问题:

// 子类UserController改造后核心代码
export class UserController extends Controller {
  // ...其余代码不变

  // 改为普通类方法(原型方法)
  getAllUsers(request: express.Request, response: express.Response) {
    response.send(this.users);
  }

  createAPost(request: express.Request, response: express.Response) {
    const user = request.body;
    this.users.push(user);
    response.send(user);
  }

  initializeRoutes(): void {
    // 注册时绑定this,避免回调执行时上下文丢失
    this.router.get(this.path, this.getAllUsers.bind(this));
    this.router.post(this.path, this.createAPost.bind(this));
  }
}

该方案可以保留基类构造中initializeRoutes()的调用逻辑,不需要子类额外处理。

方案3:工厂模式统一初始化

如果需要收拢初始化逻辑,避免子类漏写调用,可以用工厂函数统一创建Controller实例:

// 工厂函数定义
export function createController<T extends Controller>(ControllerCtor: new (path: string) => T, path: string): T {
  const instance = new ControllerCtor(path);
  instance.initializeRoutes();
  return instance;
}

// 使用示例
const userController = createController(UserController, '/users');

内容的提问来源于stack exchange,提问作者Błażej Kubiński

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 06:36:06