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

JavaScript类中调用this方法报错:this.generateWallet不是函数

问题根因

问题出在路由配置环节:你将DashboardController.wallet方法直接赋值给路由的handler属性时,已经把方法和原控制器实例的this绑定解绑了。当Express收到请求触发这个处理函数时,函数内部的this不再指向你导出的DashboardController实例,自然找不到挂载在实例上的generateWallet方法。
你之前查阅的回调中正确this指向的内容其实已经覆盖了这个核心原理——只要把对象/类实例的方法单独抽出来当回调参数传递,就会丢失原有上下文,和你用类语法还是普通对象语法没有区别。
另外你现有代码还有一个隐藏bug:generateWallet方法内部直接使用了req对象,但这个方法并没有接收req作为入参,等你修复this问题后会遇到req is not defined的报错,需要一并处理。

可行解决方案

选任意一种即可:

  • 方案1:路由注册时显式绑定实例上下文
    修改routes/api/dashboard.js的路由配置,用bind把方法的this固定到控制器实例上:
    const DashboardController = require("../../app/controller/api/dashboard-controller");
    const { AuthMiddleware } = require("../../app/middleware/auth");
    module.exports = {
      group: {
        prefix: "/dashboard",
        middleware: [AuthMiddleware],
      },
      routes: [
        {
          method: "get",
          path: "/",
          handler: DashboardController.index.bind(DashboardController),
        },
        {
          method: "get",
          path: "/wallet",
          handler: DashboardController.wallet.bind(DashboardController),
        },
      ],
    };
    
    这个方案不需要改动控制器内部逻辑,只需要调整路由定义。
  • 方案2:控制器内用类字段+箭头函数固定this
    箭头函数没有自身的this,会直接继承定义时所在作用域的this(也就是类实例),修改控制器代码:
    class DashboardController {
    
      wallet = async (req, res) => {
        let wallet = await UserWalletRepository.find({
          user_id: req.authUser.id,
        });
    
        if (wallet) return res.send(wallet);
        // 记得把req传给generateWallet
        let newWallet = await this.generateWallet(req); 
    
        res.send(newWallet);
      }
    
      generateWallet = async (req) => {
        let generatedWallet = await WalletService.generateWallet();
        let newWallet = await UserWalletRepository.create({
          user_id: req.authUser.id,
          ...generatedWallet,
        });
    
        return newWallet;
      }
    }
    
    module.exports = new DashboardController();
    
  • 方案3:路由handler用匿名函数包裹调用
    不直接传递方法引用,而是在路由回调里显式通过控制器实例调用对应方法,this会自动指向实例:
    routes: [
      {
        method: "get",
        path: "/",
        handler: (req, res) => DashboardController.index(req, res),
      },
      {
        method: "get",
        path: "/wallet",
        handler: (req, res) => DashboardController.wallet(req, res),
      },
    ]
    

注意:你之前判断路由代码不会造成影响是错误的——this丢失的时机就是你把方法从实例上拆下来单独赋值给handler的那一刻,和后续函数执行到哪一行没有关系。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 01:21:34