Javascript 避免winjs EventListeners内存泄漏

Javascript 避免winjs EventListeners内存泄漏,javascript,memory-leaks,windows-8,winjs,Javascript,Memory Leaks,Windows 8,Winjs,我想知道如果我将事件侦听器添加到按钮,是否必须在unload上删除它?按下“后退”按钮会自动删除当前页面元素中我不需要担心内存泄漏的所有内容吗 (function () { "use strict"; ui.Pages.define("/pages/registraton/registraton.html",{ ready: function (element, options) { document.getElementById("submitRegister").ad

我想知道如果我将事件侦听器添加到按钮,是否必须在
unload
上删除它?按下“后退”按钮会自动删除当前页面元素中我不需要担心内存泄漏的所有内容吗

(function () {
"use strict";
ui.Pages.define("/pages/registraton/registraton.html",{
    ready: function (element, options) {
        document.getElementById("submitRegister").addEventListener(
            "click", postRegistration , false);

    },
    unload: function () {
        document.getElementById("submitRegister").removeEventListener(
       "click", postRegistration, false);
    }
});...

提前感谢。

您需要担心WinJS.navigation命名空间所提升的单页导航模型中的内存泄漏问题

您建立的模型——您在其中实现卸载——绝对是正确的方法。您希望获得的复杂性和深度取决于应用程序的复杂性。具体来说,如果您有多个控件,并且有多个手动事件处理程序,那么您可能需要创建一组帮助程序,以使您能够一次性清理这些处理程序。这可能与将元素、事件名称和处理程序实例推送到数组中一样简单。当离开该页面并从DOM中销毁/删除它时,您只需在数组中烧掉需要清理的项即可

注意,您只需要显式地清理处理程序和DOM对象具有不同生存期的情况。如果它们一起消失——例如,一个附加到页面中DOM元素的控件,那么您不必显式地清理所有内容。垃圾收集器最终会将其清理干净。如果您是一个内存特别大的应用程序,那么通过更积极地删除侦听器,您可能会在这里获得一些胜利

还有一些事情需要记住:

  • 这也适用于实现addEventListener契约的纯javascript对象,即列表视图
  • 不要使用attachEvent——由于它的旧实现是隐藏的,它将导致不可破坏的循环。它实际上是一个不推荐使用的API,因此无论如何都不应该使用它
  • 当您在绑定了this指针的位置提供事件处理程序时,在尝试解除绑定它们时,请小心。例如
例如:

var element = getInterestingElement();
element.addEventListener("click", this.handleClick.bind(this));
如果尝试分离事件,您将丢失--.bind()中的返回值将丢失在风中,您将永远无法解开它:

var element = getInterestingElement();
element.removeEventListener("click", this.handleClick); // Won't remove the listener
element.removeEventListener("click", this.handleClick.bind(this)); // Won't remove, since it's a different function object
这里的最佳解决方案是在连接之前,先单击monkey patch
handleClick
: this.handleClick=this.handleClick.bind(this)

或将其储存起来以备日后使用:

this.handlerClickToCleanup = this.handleClick.bind(this);
element.addEventListener("click", this.handleClickToCleanup);

删除事件侦听器后执行此操作是否有意义。handlerClickToCleanup=null?或者元素=null?