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

继承WebSocket类实例化报错:需使用new运算符构造DOM对象

解决WebSocket子类实例化的TypeError问题

这个报错我之前也碰到过,核心原因很清楚:像WebSocket这种浏览器提供的原生DOM构造函数,内部有特殊的实例创建逻辑,不允许用WebSocket.call(this, ...)这种方式在自定义构造函数里调用,必须通过new操作符来生成实例。你用的ES5原型继承方式对普通自定义构造函数没问题,但对这类原生宿主对象行不通。

下面给你两种可行的解决办法:

方案一:用ES6的class extends语法(首推)

ES6的class原生支持继承这类原生构造函数,浏览器会自动处理好内部的实例创建逻辑,写法也更简洁规范:

class WebConnect extends WebSocket {
  constructor() {
    // 必须先调用super执行父类构造,不能先写this相关代码
    super("wss://ws.achex.ca/");
  }

  onopen(evt) {
    console.log("连接已打开", evt);
  }

  anotherWsFunction() {
    // 这里写你的自定义方法逻辑
    console.log("触发自定义WebSocket方法");
  }
}

// 现在实例化就不会报错了
const a = new WebConnect();

方案二:ES5兼容方案(包装原生实例)

如果需要兼容老版本浏览器,可以通过直接创建原生WebSocket实例再扩展的方式实现类似效果:

function WebConnect() {
  // 直接用new创建原生WebSocket实例
  const ws = new WebSocket("wss://ws.achex.ca/");
  
  // 给实例添加自定义方法
  ws.anotherWsFunction = function() {
    console.log("触发自定义WebSocket方法");
  };
  
  // 重写onopen回调
  ws.onopen = function(evt) {
    console.log("连接已打开", evt);
  };
  
  // 返回这个扩展后的实例
  return ws;
}

// 实例化测试
const a = new WebConnect();

这种方式本质是包装原生实例,虽然不是严格意义上的子类继承,但完全能满足你扩展WebSocket功能的需求。

补充说明

原生DOM构造函数和普通JS构造函数的底层实现不一样,它们的实例是由浏览器内核创建的,不允许通过call/apply来篡改this指向并生成实例。而ES6的extends语法专门针对这类场景做了适配,所以能正常工作。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:36:01