gpt4 book ai didi

javascript - 为什么会在 Internet Explorer 8 中泄漏?

转载 作者:可可西里 更新时间:2023-11-01 02:25:22 26 4
gpt4 key购买 nike

为什么下面的代码会泄露?

for (var i = 0; i < 100; i++) {
var item = {};
item.elem = document.createElement('div');
document.body.appendChild(item.elem);
item.addEvent = function(name,listener) {
var self = this;
var wrappedListener = function() {
return listener.apply(self,arguments);
}
//Uh-oh creating a circular reference here!
//The wrappedListener has a closure on self and therefore on item.elem.
addEvent(this.elem,name,wrappedListener);
return wrappedListener;
}
var wrap = item.addEvent('eventName',listen);

//Now remove the eventHandler - this should free up the circular reference.
removeEvent(item.elem, 'eventName', wrap);
if (item.elem.parentNode) {
item.elem.parentNode.removeChild(item.elem);
}
//item.elem = null; //With this also un-commented, the leak disappears.
//The fact that I have to null item.elem tells me that something is holding
//a reference to item, and therefore elem. Setting elem to null fixes the
//problem, but since I am removing the event handler, I don't think this
//should be required.
}

注意:addEventremoveEvent 只是抽象attachEvent/addEventListener Internet Explorer 与其他浏览器的区别.

我创建了一个 jsFiddle演示问题的项目。只需启动 Internet Explorer 8,然后在任务管理器或 Process Explorer 中观察它的运行情况。此外,您将在此处看到 addEventremoveEvent 的定义。

http://jsfiddle.net/rJ8x5/34/

编辑:好吧,我想出了以下解决方案。它不漂亮,但它有效! http://jsfiddle.net/rJ8x5/43/

var item = {};
item.elem = document.createElement('div');
document.body.appendChild(item.elem);
item.addEvent = function(name,listener) {
var wrappedListener = function() {
//Access the scope through the callee properties.
return listener.apply( arguments.callee.scope, arguments);
}
addEvent(this.elem,name,wrappedListener);
//Save the scope not as a closure, but as a property on the handler.
wrappedListener.scope = this
return wrappedListener;
}
var wrap = item.addEvent('eventName',listen);
removeEvent(item.elem, 'eventName', wrap);
//Force the circular reference to GO AWAY.
wrap.scope = null
if (item.elem.parentNode) {
item.elem.parentNode.removeChild(item.elem);
}
//item.elem = null; //No longer needed.

最佳答案

问题是事件(顺便说一句,几乎总是在 Internet Explorer 中)。

http://jsfiddle.net/rJ8x5/39/并注意它如何很好地收集垃圾。

当您附加事件时,您正在创建循环引用。在 Circular references to DOM objects on an HTML page cause a memory leak 中阅读更多相关信息.

关于javascript - 为什么会在 Internet Explorer 8 中泄漏?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4903379/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com