为什么Internet Explorer 8中会出现这种情况? [英] Why does this leak in Internet Explorer 8?

查看:107
本文介绍了为什么Internet Explorer 8中会出现这种情况?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Why does the following code leak?

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.
}

注意: addEvent removeEvent 只是抽象 attachEvent / addEventListener 之间的差异Internet Explorer和其他浏览器。

Note: addEvent and removeEvent are just to abstract attachEvent/addEventListener differences between Internet Explorer and other browsers.

我创建了一个 jsFiddle 项目这证明了这个问题。只需启动Internet Explorer 8并在任务管理器或Process Explorer中查看它。此外,您将看到 addEvent removeEvent 的定义。

I created a jsFiddle project which demonstrates the problem. Just fire up Internet Explorer 8 and watch it go in Task Manager or Process Explorer. Also, you will see the definition of addEvent and removeEvent there.

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

编辑:嗯,我提出了以下解决方案。它不漂亮,但它的工作原理!
http://jsfiddle.net/rJ8x5/43/

Well, I came up with the following solution. It is not pretty, but it works! 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.


推荐答案

问题在于事件(几乎总是在互联网上) Explorer,BTW)。

The problem is the events (as almost always in Internet Explorer, BTW).

查看 http:// jsfiddle.net/rJ8x5/39/ 并注意垃圾如何收集罚款。

Look at http://jsfiddle.net/rJ8x5/39/ and notice how it garbage collects fine.

您在附加事件时创建循环引用。在 在HTML页面上对DOM对象的循环引用导致内存泄漏中了解有关它的更多信息

You are creating circular references when you attach the events. Read more about it in Circular references to DOM objects on an HTML page cause a memory leak.

这篇关于为什么Internet Explorer 8中会出现这种情况?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆