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

TypeScript类方法调用报错:Cannot read properties of undefined

问题:调用类方法时触发TypeError:Cannot read properties of undefined (reading 'onOpenMessage')

项目编译无错误,但在控制器中调用类方法时触发TypeError,提示Cannot read properties of undefined (reading 'onOpenMessage')。将私有方法onOpenMessage改为公有也无法解决问题,同类代码在其他项目可正常运行。

报错堆栈信息

TypeError: Cannot read properties of undefined (reading 'onOpenMessage')
at WebSocket. (/Users/xxx/redqueen-middleware/src/controllers/websocket.ts:23:16)
at WebSocket.onMessage (/Users/xxx/redqueen-middleware/node_modules/ws/lib/event-target.js:132:16) at WebSocket.emit (node:events:513:28)
at Receiver.receiverOnMessage (/Users/xxx/redqueen-middleware/node_modules/ws/lib/websocket.js:1068:20)
at Receiver.emit (node:events:513:28)
at Receiver.dataMessage (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:517:14)
at Receiver.getData (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:435:17)
at Receiver.startLoop (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:143:22)
at Receiver._write (/Users/xxx/redqueen-middleware/node_modules/ws/lib/receiver.js:78:10)
at writeOrBuffer (node:internal/streams/writable:391:12)
[ERROR] 16:46:06 TypeError: Cannot read properties of undefined (reading 'onOpenMessage')

相关代码

控制器代码(websocket.ts)

class WebsocketController {
  initWebsocket(websocket: WebSocket): void {
    //some code, works fine before calling method `onOpenMessage`
    this.onOpenMessage();
  }

  private onOpenMessage(): void {
    //some code
  }
}

export default new WebsocketController();

tsconfig.json配置

{
  "compilerOptions": {
    "module": "commonjs",
    "declaration": false,
    "noImplicitAny": false,
    "removeComments": true,
    "noLib": false,
    "allowSyntheticDefaultImports": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es6",
    "esModuleInterop": true,
    "lib": [
      "dom",
      "es6",
      "esnext.asynciterable"
    ],
    "typeRoots": [
      "./custom_typings",
      "./node_modules/@types"
    ],
    "sourceMap": true,
    "allowJs": true,
    "outDir": "./build",
    "baseUrl": "./src",
    "resolveJsonModule": true
  },
  "include": [
    "src/**/*",
    "config/**/*"
  ],
  "exclude": [
    "node_modules",
    "**/*.spec.ts",
    "**/*.test.ts",
    "custom_typings"
  ]
}

server.ts代码

import express from 'express';
import expressWs from 'express-ws';
import winston from 'winston';

import WebsocketController from './controllers/websocket';

export default function initServer() {
  const app = express();
  const port = process.env.PORT;
  const router = express.Router();
  global.websocketsList = [];

  expressWs(app);

  router.ws('/ws-request', WebsocketController.initWebsocket);

  app.use('/', router);

  app.listen(port, () => {
    winston.info(`Middleware server start on port ${port}`);
  });
}

解决方案

问题根源是**this上下文丢失**:在server.ts中直接传递WebsocketController.initWebsocket作为回调时,该方法的this不再绑定到控制器实例,调用时this为undefined,导致无法读取onOpenMessage属性。

有两种修复方式:

方式1:用箭头函数包裹回调

修改server.ts中的路由注册代码:

router.ws('/ws-request', (ws) => WebsocketController.initWebsocket(ws));

箭头函数会自动捕获当前上下文,确保initWebsocket中的this指向控制器实例。

方式2:手动绑定this到实例

同样修改路由注册代码:

router.ws('/ws-request', WebsocketController.initWebsocket.bind(WebsocketController));

通过bind方法强制将this绑定到控制器实例,避免上下文丢失。

两种方式都能解决问题,任选其一即可。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 16:55:30