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

ES6类中WebSocket消息接收时方法未定义,无法访问外部上下文

解决WebSocket事件触发时"Cannot read property 'wsHandler' of undefined"的问题

这个报错核心是**this的指向错误**,再加上代码里藏着几个小bug,咱们一步步拆解修复:

1. 先揪出代码里的基础错误

  • 构造函数里的this.ws==null是比较操作,应该改成赋值语句:this.ws = null;
  • intialize拼写错误,正确写法是initialize(少了个字母i)

2. 核心问题:onmessage_recieved里的this指向跑偏了

当你用this.ws.addEventListener('message', this.onmessage_recieved)绑定事件时,事件触发后,onmessage_recieved里的this会指向WebSocket实例本身,而不是你的WebSocketSender对象,自然就找不到wsHandler了。另外你在构造函数里定义的_self是局部变量,外部方法根本访问不到,所以this._self也是undefined。

修复方案有两种,选哪种都能解决问题:

方案一:用箭头函数绑定上下文

把事件监听的回调改成箭头函数,这样this会继承外层的WebSocketSender实例上下文:

this.ws.addEventListener('message', (e) => this.onmessage_recieved(e));

同时修改onmessage_recieved方法,直接用this访问wsHandler:

onmessage_recieved(e) {
  debugger;
  let jsonData = JSON.parse(e.data);
  this.wsHandler.onMessageReceived(jsonData);
}

方案二:在构造函数里提前绑定方法的this

在构造函数里把onmessage_recieved的this固定到当前实例:

constructor(wsHandler) {
  this.wsHandler = wsHandler;
  this.ws = null; // 修复赋值错误
  this.url = '';
  // 绑定this指向,确保方法里的this永远指向WebSocketSender实例
  this.onmessage_recieved = this.onmessage_recieved.bind(this);
}

这样后续添加事件监听时直接写this.ws.addEventListener('message', this.onmessage_recieved)就行,方法里的this不会再跑偏。

3. 完整修复后的代码

class WebSocketSender {
  constructor(wsHandler) {
    this.wsHandler = wsHandler;
    this.ws = null; // 修复赋值错误
    this.url = '';
    // 方案二的话加上这行绑定:
    // this.onmessage_recieved = this.onmessage_recieved.bind(this);
  }
  
  initialize(url, sender) { // 修复拼写错误
    this.url = url;
    this.ws = new WebSocket(url);
    this.ws.onopen = () => console.log("opened");
    this.ws.onclose = () => console.log("closed");
    this.ws.onerror = () => console.log("error");
    // 方案一用箭头函数:
    this.ws.addEventListener('message', (e) => this.onmessage_recieved(e));
    // 方案二直接写:
    // this.ws.addEventListener('message', this.onmessage_recieved);
  }
  
  send(data) {
    if (this.ws?.readyState === 1) { // 可选:用可选链避免ws为null时报错
      this.ws.send(data);
    }
  }
  
  onmessage_recieved(e) {
    debugger;
    let jsonData = JSON.parse(e.data);
    this.wsHandler.onMessageReceived(jsonData);
  }
  
  close() {
    if (this.ws?.readyState === 1) { // 可选:用可选链避免ws为null时报错
      this.ws.close();
    }
  }
}

额外优化建议

  • 在send和close方法里用可选链this.ws?.readyState,可以避免this.ws还没初始化或者已经关闭时出现额外报错。
  • 写代码时多注意拼写细节,像intialize这种小错误很容易浪费排查时间~

内容的提问来源于stack exchange,提问作者Praveen Kumar N

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:56:06