如何在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
相关产品推荐
相关产品推荐

