jQuery中replaceWith替换元素后原绑定事件的内存回收问题
原按钮绑定的Click事件处理函数会被垃圾回收吗?
嘿,这个问题问得挺到位的,我来给你掰扯清楚:
结论先行:如果没有其他代码还"抓着"原按钮DOM元素不放,那它绑定的click事件处理函数会跟着原元素一起被浏览器的垃圾回收(GC)机制清除掉。
具体来说是这么回事:
- 当你调用
replaceWith()把原按钮换成新按钮时,原按钮的DOM节点会被从DOM树里彻底移除,变成一个"没人管"的游离元素。 - jQuery给元素绑定的事件处理函数,是和这个元素实例绑定在一起的。如果这个游离的原按钮没有被任何活跃的JavaScript变量、闭包或者其他对象引用(比如你没把它存在全局变量里,也没在某个闭包里保留它的引用),浏览器的垃圾回收器就会判定它是无用的内存占用,把原元素以及绑定在它身上的事件处理函数一并回收掉,释放内存。
- 但要是你之前把原按钮存到了某个变量里(比如
const myOldBtn = $('button')[0]),或者有闭包捕获了这个元素,那这个原元素和它的事件处理函数就会一直留在内存里,直到你把这些引用彻底解除(比如把变量设为null)。
给你举两个直观的例子:
// 例子1:无额外引用,会被GC回收 $('button').on('click', function() { alert('点到我啦') }); $('button').replaceWith('<button>新按钮</button>'); // 原按钮和它的click函数很快就会被垃圾回收 // 例子2:有额外引用,暂时不会被回收 const oldBtn = $('button')[0]; $('button').on('click', function() { alert('点到我啦') }); $('button').replaceWith('<button>新按钮</button>'); // 因为oldBtn还拿着原按钮的引用,所以它和事件函数都留在内存里 // 直到你执行oldBtn = null,GC才有可能回收它们
另外要提一句:如果是用事件委托(比如在父元素上绑定事件,委托给按钮),那事件处理函数是绑定在父元素上的,和原按钮没关系,这种情况就不在咱们这个问题的讨论范围内啦。
内容的提问来源于stack exchange,提问作者CryptoBird




