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

如何在JavaScript中重写原型构造函数并拦截EventSource实例创建?

如何在JavaScript中重写原型构造函数并拦截EventSource实例创建?

嗨,我懂你现在碰到的问题了——想拦截所有EventSource的实例创建,但直接修改EventSource.prototype.constructor没效果,不过给原型加自定义方法却能正常工作对吧?这其实是因为构造函数的调用逻辑和原型方法完全不一样,我来给你讲清楚怎么解决这个问题。

为什么你之前的方法没用?

你尝试修改EventSource.prototype.constructor,但实际上当你用new EventSource(...)创建实例时,JavaScript会直接调用全局的EventSource函数,根本不会去原型上找constructor属性。原型上的constructor更多是一个标识性的属性,并不是实际触发实例创建的入口,所以修改它自然不会生效。

正确的拦截方案:包裹原生构造函数

要拦截所有实例创建,我们需要直接替换全局的EventSource构造函数,用自己的函数包裹原生逻辑,这样所有new EventSource(...)的调用都会经过我们的拦截代码。具体做法如下:

// 先保存原生的EventSource构造函数,避免丢失功能
const OriginalEventSource = window.EventSource;

// 替换全局的EventSource为我们的拦截函数
window.EventSource = function(url, config) {
    // 调用原生构造函数创建真实实例
    const instance = new OriginalEventSource(url, config);
    
    // 这里加入你的拦截逻辑,比如日志、参数修改等
    console.log("EventSource实例创建被拦截!目标URL:", url);
    
    // 返回原生实例(也可以根据需求返回自定义对象)
    return instance;
};

// 对齐原型链,确保原生方法和自定义原型方法能正常使用
window.EventSource.prototype = OriginalEventSource.prototype;
window.EventSource.prototype.constructor = window.EventSource;

测试一下效果

现在你再创建EventSource实例,就能看到拦截逻辑生效了,同时原来的原型方法也不受影响:

// 测试拦截逻辑
const es = new EventSource("my-data");
// 控制台会输出:EventSource实例创建被拦截!目标URL: my-data

// 原来的自定义原型方法依然可用
es.sayHi(); // 弹出"Hi"

一些额外的注意事项

  • 一定要先保存原生构造函数,不然会陷入无限递归,或者直接丢失EventSource的原生功能
  • 对齐原型链很关键,这能保证实例的instanceof EventSource判断正常,同时原生的原型方法(比如close())也能正常调用
  • 如果需要修改构造参数(比如给URL统一加前缀),可以在调用OriginalEventSource之前对url或config做修改

内容来源于stack exchange

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.08 09:43:02