JavaScript中WebSocket对象超出作用域后未被销毁的原因是什么?
为什么WebSocket实例在函数执行完后仍能正常工作?
先看你贴的这段代码:
function connect() { var ws = new WebSocket(url); ws.onmessage = function(e) { window.alert(e.data); }; }
这段代码能正常运行,核心原因和垃圾回收规则、WebSocket的宿主特性直接相关:
- 垃圾回收的核心是「可达引用」:当
connect()执行完毕,你定义的局部变量ws确实会跳出当前作用域,但这不代表WebSocket实例会被回收——因为浏览器的WebSocket运行时模块会持有这个实例的引用。只要连接处于活跃状态,浏览器就需要通过这个实例管理网络连接、收发数据,自然不会让它被垃圾回收器清理。 - 事件监听器不是根本原因:虽然
onmessage的回调函数会因为闭包持有ws的引用,但就算你不绑定任何事件,只要WebSocket连接没断开,这个实例依然不会被回收。反过来,如果连接关闭,浏览器会释放内部的引用,这时候如果没有其他地方(比如闭包)持有它,垃圾回收器才会把它清理掉。
简单总结:WebSocket是浏览器提供的宿主对象,它的生命周期不完全由JS的作用域和闭包决定,更多由浏览器的网络连接状态控制。
内容的提问来源于stack exchange,提问作者Maestro
相关产品推荐
相关产品推荐

