gpt4 book ai didi

javascript - 检测 JavaScript 中的内存泄漏

转载 作者:数据小太阳 更新时间:2023-10-29 04:28:12 25 4
gpt4 key购买 nike

我有这段代码,我在为项目构建的一些 JavaScript 组件上使用了它。现在我想知道以下代码是否存在内存泄漏。

哪个选项最合适,A 或 B 还是有更好的方法?

var component = function(){
var self = this; //A - not sure there's a leak here

this.foo = function(){
//var self = this; //B. I can do this but I want to use self in other method as well
var dom = getElementById('someid');
dom.onclick = function(){
self.foo2(); // here I used the self reference
//i cannot use this here, because it refer to dom
}
}

this.foo2 = function(){
var dom = getElementById('someid');
dom.onclick = function(){
self.foo2(); //here I used the self reference
//i cannot use this here, because it refer to dom
}
}
};

// some usage

var c1 = new component();
c1.foo();

最佳答案

内存消耗

这种方法的问题是 全部 对于每个实例,您所有方法的代码都将被复制,这可能会导致大量内存消耗(除非围绕您无法依赖的执行上下文进行漂亮的优化)。您所做的好处是单击处理程序直接调用您希望它调用的方法。

通常的做法是通过将方法放在原型(prototype)上来在实例之间共享方法,并且例如在包含良好的闭包上下文(例如,不关闭无关数据的闭包上下文)中构建小的包装函数——通常出于这个原因由帮助函数创建 - 设置对实例的调用。这样,每个实例只复制少量代码,大部分代码是共享的。代价是每次点击都需要调用一个函数,然后转身并调用另一个函数,但坦率地说,除了非常紧凑的循环(点击处理程序不是),开销并不是真正的问题,而内存消耗确实可以成为当今网络应用程序中的一个问题。

在原型(prototype)上设置函数在其他地方都有很好的介绍,通常通过帮助程序处理,这些帮助程序让您比原始 JavaScript 更清晰、更简洁。有关包含完善的闭包上下文中的包装器构建器的示例,请查看 Function#bind Prototype 中的实现(或其他几个 JavaScript 库中的类似函数,如 MooTools、Closure 库等)

基础看起来像这样,但我实际上不会这样做:

var component = function() {
this.boundFoo = bind(this, foo); // Remove this if you never use it as a handler
this.boundFoo2 = bind(this, foo2);
};
component.prototype.foo = function() {
var dom = getElementById('someid');
dom.onclick = this.boundFoo2;
};
// (Isn't this exactly what foo did?)
component.prototype.foo2 = function() {
var dom = getElementById('someid');
dom.onclick = this.boundFoo2;
};
function bind(context, func) {
return function() {
func.apply(context, arguments);
};
}

注意 bind接受上下文和函数,并返回一个新函数,该函数将使用该上下文调用给定函数。

您还可以在分配函数时绑定(bind)函数,而不是将它们设置为实例上的属性,但如果您要重用它们(如上所示),那么保留一份副本就可以实现。

上面有问题(所有的函数都是匿名的,这意味着你的工具不能帮助你)但是没有进入对象辅助函数,这是基本的想法。

内存泄漏

“Crescent Fresh”指出我最初并没有真正解决内存泄漏问题。要解决的一个重要方面是,对于某些浏览器(主要是 IE 和衍生产品),在完成事件处理程序时(例如,离开页面时)解开事件处理程序很重要。所以你的 onclick如果您稍后不清除它们,分配可能是某些浏览器上的内存泄漏。这是因为当 DOM 元素和 JavaScript 对象仍然没有被引用时,所涉及的浏览器不会处理清理循环引用(例如,它们相互引用但没有其他任何引用)。您必须断开 DOM 元素和 JavaScript 函数之间的链接,以确保两者都被清除。如果您使用它们的方法来附加事件处理程序,则像 Prototype 这样的库会在页面卸载时为您执行此操作;我不太了解其他库,无法评论他们是否这样做。

其他注意事项

有点过时,但是:
  • 还要研究“事件委托(delegate)”的概念——点击处理程序是使用委托(delegate)的好地方,因为它们会冒泡。您可能会发现在容器级别只需要几个处理程序,而不是在元素级别需要数百个处理程序。
  • 而不是分配给 onclick元素的属性,称为设置事件处理程序的“DOM0”样式,请考虑使用较新的(90 年代后期)机制来执行此操作: addEventListener 在符合标准的浏览器和 attachEvent 在 IE 上。这样做的一大改进是可以为同一元素上的同一事件设置多个处理程序,而对于 DOM0 处理程序,如果那里有一个,则分配一个新的处理程序会破坏旧的处理程序。
  • 关于javascript - 检测 JavaScript 中的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1871821/

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