【问题标题】:When should I use the destroy method?什么时候应该使用destroy方法?
【发布时间】:2016-01-03 12:39:57
【问题描述】:

我做了一个small javascript framework,旨在在原型对象模型中添加一些有用的东西(超级方法调用、继承、自动初始化......)。

在这个框架中,一些对象方法会被自动调用,比如“init”构造对象和“destroy”窗口卸载。

我对这种销毁方法有两个问题:

  • 这个方法有什么用?

我认为它应该对 DOM 对象(解除绑定事件)进行一些清理,但还有其他清理工作要做吗?

  • 是否应该在另一个事件上调用此方法?是否可以检测到对象何时被销毁并在此时调用此方法?

如果有人对这个框架感兴趣,我把它发布在 gitHub 上,但现在没有文档 :-/ : https://github.com/LeMisterV/EasyPrototype

【问题讨论】:

  • 卸载时调用销毁?好吧,该方法可以做任何事情 - 因为它不会对其他任何事情产生任何影响。毕竟,浏览器无论如何都会离开该页面。销毁方法对在网页生命周期内销毁的组件有意义。与桌面应用不同的是,Web 应用的“卸载”无需清理任何东西,桌面应用利用机会将缓冲区写入磁盘、释放文件句柄等。
  • 在 Javascript 中,不可能编写一个在对象被“销毁”时/之前自动调用的方法,必须显式调用它。 JS中的“破坏”是什么意思?当对象被垃圾收集时 - 这是随机的?什么时候释放它的最后一个句柄?
  • 我怀疑@Nicolas 担心 IE 中的内存泄漏,当 DOM 元素具有值为 JavaScript 对象的属性时,这会出现问题,尤其是。关闭。 DOM 内存管理器不知道如何回收该空间,因此它不会。
  • @Pointy:即使在 IE 中,UNLOAD 也没有内存泄漏,通常,destroy() 在其他浏览器中也可以这样做 - 如果组件在页面的生命周期内被销毁(有些应用程序不使用显示/隐藏小部件,但每次都会执行一个新的 Widget()/widget.destroy() 循环。
  • @Mörre 我认为 IE6 肯定存在循环引用问题,这些问题在浏览器进程的生命周期内不会被释放。 Here 是微软的一篇文章,还有许多其他人可以描述这个问题。

标签: javascript destructor


【解决方案1】:

一个更好的问题,为什么你需要摧毁任何东西?如果窗口正在卸载,所有内容都将代表您进行垃圾收集。

【讨论】:

  • 不需要垃圾回收,这可能是一个相当昂贵的过程——整个内存可以被释放。 GC 是在应用程序运行期间发生的过程,并且(通常)仅在确实需要时(因为运行 GC 不是“免费”)
  • 这里的理论和实践有很大的不同。当您开始进行历史导航和保存状态时,这要复杂得多。事情不会立即被 GC 处理。此外,你和我都知道卸载时应该对所有内容进行 GC,但至少在 IE 中,这不是保证。
  • 那个 GC 错误只影响 IE 6。你可以争辩说有些程序员仍然关心 - 但请....我不确定我是否听说过它会影响它,即使离开页面- 你有参考吗?
  • 查看我的 cmets 了解上述问题。
【解决方案2】:

某些版本的 Internet Explorer 会卡在 JavaScript 和 DOM 之间的循环引用上,因为它们是单独进行垃圾收集的。当您开始向所有内容添加事件处理程序时,这往往会成为一个问题。

您应该在框架中做的是跟踪每次添加事件,以便您可以遍历该事件数组并在卸载时销毁每个事件。

【讨论】:

  • 出于好奇,IE的哪个版本有这个问题?其他主要框架是否手动跟踪添加的事件处理程序?
  • 因为它不能保证在某些浏览器中自动发生,所以你正在解决它们的内存泄漏问题。
  • IE6 有这个问题。如果有人声称其他浏览器,我希望看到参考。
  • @Thr4wn:至少达到 IE7。 jQuery 比我更优雅地处理它。您可以在 jQuery.event.add 函数中看到它,从 jquery 1.6.1 的第 2515 行开始
  • 澄清一下,IE7 是否有内存泄漏问题?还是说 IE 版本严格低于 7?
【解决方案3】:

首先,“破坏”(或任何析构函数)的原因是让您的“系统”或程序进入已知的稳定状态。在浏览器中,所有内存使用(这是经典问题)都会自动使用Garbage Collection 为您完成。

因此,您可能需要析构函数(“destroy”方法)的唯一原因是,您的系统是否存在抽象属性,对象需要确保处于已知状态。

【讨论】:

  • 不完全。示例:如果一个应用程序被编写为使用“btn = new Button()”和“btn.destroy()”而不是创建按钮,然后在其上使用 hide()/show(),destroy() 是非常必要的。它删除了小部件的 DOM 元素,相当于 hide()。这是合法的编程,尽管我通常更喜欢只实例化一次。
  • 这个例子不适合我的描述吗?或者我应该调整我的解释。在 DOM 中挂着一个松散的按钮是我认为“不稳定”的,因此确实表明需要一个析构函数。我想“去除剩余物”比“使系统稳定”更能概括地描述析构函数
  • 您在阅读时的描述当然不是错误的,而是针对桌面应用程序中的“将未保存的缓冲区写入磁盘”之类的内容。进行隐藏/显示类型编程是另一回事,您的似乎更多用于“内部问题”,而这是“故意的外部用户目标效果”。
猜你喜欢
  • 2010-09-22
  • 2012-03-23
  • 1970-01-01
  • 2023-04-02
  • 2011-04-15
  • 2017-04-10
  • 2012-03-19
  • 2018-05-12
  • 2018-12-11
相关资源
最近更新 更多