繁体   English   中英

Javascript:在原型继承中删除对HTML选择器的引用?

[英]Javascript: Remove reference to HTML selectors in prototype inheritence?

我正在忙于学习使用对象进行原型继承。 我的代码当前可以正常工作。 但是我现在想做的是避免造成内存泄漏。

我有一堆在父对象中被调用的HTML选择器。 这些稍后将用于删除和添加一些CSS动画。

我现在想要做的是基本上删除或使父构造函数变得不确定,并使它的子代不引用那些选择器。

这是代码共享,因为我不想将其全部转储到这里。 但有疑问的是,父母是:

    var GameStartup = function() {
    this.welcomeStartBtn = document.querySelector('.game-startup__welcome a');
    this.welcomeStartBtn__controller = document.querySelector('.game-startup__welcome a span:first-child');
    this.welcomeStartBtn__copy = document.querySelector('.game-startup__welcome a span:last-child');
};

因此,基本上,我希望其子项ShowLogin和父项未定义或类似的东西,以使其不再能够创建诸如分离的dom节点之类的东西。

您可以做的一件事是像这样使用吸气剂:

function GameSartup () {}

GameSartup.prototype = {
    constructor: GameSartup,

    get welcomeStartBtn () {
        return document.querySelector('.game-startup__welcome a');
    }

    // more getters here
}

这样,您可能会有一些开销,因为每次“获取” DOM元素时都要查询dom,但是会根据要求删除所有引用。

如果这会使速度减慢太多,则可以为元素引用创建缓存,如下所示:

function GameSartup () {
    this.domcache = {};
}

GameSartup.prototype = {
     constructor: GameSartup,

    get welcomeStartBtn () {
        var selector = '.game-startup__welcome a';
        if (!this.domcache.hasOwnProperty(selector)) {
            this.domcache[selector] = document.querySelector(selector);
        }
        return this.domcache[selector];
    },

    // more getters here

    trash: function () {
        this.domcache = null;
        delete this.domcache;
    }
}

这样,您可以一次释放所有引用,但是仍然必须手动清除缓存。 但是,如果您像这样创建一个GameSartup对象:

var gs = new GameSartup();

然后:

gs = null;

并且没有其他对gs引用,垃圾收集器会发现也没有对domcache引用,并将其删除。

更新

回应评论:

“缓存失效”始终是应用程序中的关键点,缓存本身可能会变得很复杂,并且会引发奇怪的错误。 但这也可以真正加快速度。 这取决于应用程序应该/必须有多复杂。

在这种情况下,我将开始时不使用缓存,并且如果性能良好,就可以完成。

我认为下一步可以如上所述:在某些事件下立即清除整个缓存。 该方法可能如下所示:

//you do not need to loop over the cache and set the values to undefinded
//the garbage collector will free memory
//as soon as there is no reference to a given object left
clearCache: function(){
    this.domcache = {};
    return this;
}

下一步是实现»每项缓存«,如下所示:

addToCache: function (key, value) {
    if (!this.domcache.hasOwnProperty(key)) {
        this.domcache[key] = value;
    }
    return value;
}

clearFromCache(key) {
    delete this.domcache[key];
    return this;
}

在添加完项目后立即将它们从缓存中清除是没有用的,因为这只是没有缓存,加上管理它的开销。

总而言之,它取决于许多因素,例如:

  • 您需要多久查询一次元素,
  • 该元素将始终驻留在dom中,以便始终可以从dom中查询它,
  • 需要缓存多少个元素,
  • 正确缓存这些元素需要多少代码,
  • dom中有多少元素

如有疑问,您应该在有无缓存的情况下进行一些基准测试,以找到有效的解决方法。

更新#2

由于您在谈论DOM元素-只要元素是DOM的一部分(具有父节点)-垃圾收集器就不会删除它,因为存在对它的引用(childNodes数组中的项目)。

因此,如果您担心在运行时创建的由太多元素引起的内存泄漏,如下所示:

var elements = [];
for(var i = 0; i < 10000; i++) {
     var div = document.body.appendChild(document.createElement('div'));
     elements.push(div);
}

比您必须要做的两件事:从dom中删除每个元素elements[i] ,例如:

elements[i].parentNode.removeChild(elements[i]);

elements = null; //or a new array

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM