Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/376.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 为什么在InternetExplorer8中会出现此漏洞?_Javascript_Internet Explorer_Memory Leaks - Fatal编程技术网

Javascript 为什么在InternetExplorer8中会出现此漏洞?

Javascript 为什么在InternetExplorer8中会出现此漏洞?,javascript,internet-explorer,memory-leaks,Javascript,Internet Explorer,Memory Leaks,为什么下面的代码会泄漏 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 wrappedListe

为什么下面的代码会泄漏

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.
}
问题在于事件(几乎总是在Internet Explorer中,顺便说一句)

看看并注意它是如何收集垃圾的


附加事件时,您正在创建循环引用。请在中阅读更多信息。

代码泄漏是因为您调用attachEvent不正确-Microsoft坚持事件名称为标准DHTML事件

如果将
'eventName'
更改为
'click'
,则不会泄漏


一个更可靠的解决方案是,将事件附加代码更改为检查DomeElement中的
'on'+eventname
,如果这是错误的,则拒绝附加事件。

我知道IE过去有一个错误,它会对本机对象和javascript对象使用单独的垃圾收集,所以,每当您在javascript对象和本机对象之间形成一个循环时,垃圾收集器都无法清理它。是吗?我认为item指向item.elem,这是一个具有返回item的处理程序的div。-与您的问题不太相关,但您可以通过使用
listener.apply(item,arguments)
来消除
self
变量。:-)完全地但这实际上是我编写的一个类的一个简化版本,在这个类中addEvent方法无法如此方便地访问实例-因此var self=thisOpening post已经用问题的解决方案更新了!是的,因为函数在闭包中捕获对DOM元素的引用,所以当JScript对其进行垃圾收集时,DOM元素会泄漏。是吗?@Pointy:是的,这都是关于事件处理程序的作用域,或者更确切地说是关于该作用域中捕获的DOM引用:)我知道IE的循环引用相关内存泄漏。然而,这里的要点是,我要特别删除事件处理程序。这不应该破坏循环引用吗?@jordancpaul:出于某种原因,ie不理解垃圾收集处理程序是可以的,或者更具体地说,当您删除它时,它的作用域是可以的。这在ie中已经有很长一段时间了。。。请阅读以下内容:我已经用更多的评论更新了我原来的帖子,更好地说明了我为什么感到困惑。
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.