【问题标题】:Safely remove and destroy backbone objects安全移除和销毁主干对象
【发布时间】:2015-04-28 22:25:30
【问题描述】:

我正在构建一个 SPA,并试图找出一种安全且干净的方法来在离开应用程序的一个部分时删除所有主干实体。我知道 Model.destroy()、View.remove() 和 Collection.reset() 方法。我主要担心的是:

  • Model.destroy() 负责销毁服务器上的模型。是否还需要手动删除 Javascript 模型?
  • 类似地,我意识到 View.remove() 将从 DOM 中删除视图。应该如何安全地摆脱视图对象?
  • Collection.reset() 清除集合中的模型。这是否也会删除底层 Javascript 模型对象,还是需要明确删除它们?
  • 如何摆脱集合对象本身?

我的问题对某些人来说可能看起来很简单,但它们让我困惑了一段时间。我没有找到任何关于这个确切问题的有用信息,这就是我决定在这里发帖的原因。我也是一个相对较新的 Javascript 并且不知道 Javascript 的垃圾收集方案。 Javascript 是否有垃圾收集器,它会负责删除所有此类对象吗?

我也在研究删除视图的最佳方法。

  • View.remove() 仅从 DOM 中删除视图。我的猜测是,仍然需要注意删除/销毁底层模型并取消绑定所有事件侦听器。对吗?
  • 我经常使用 _.bindAll 来更改函数调用的上下文。我还没有找到解除绑定的方法。我的理解是,这是不必要的。我说的对吗?

【问题讨论】:

    标签: backbone.js collections model reset destroy


    【解决方案1】:

    这里是学习 javascript 垃圾收集的好资源:

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Memory_Management

    总而言之,使用 Backbone,您唯一需要担心的是删除视图中的自定义事件处理程序,而这样做的常见方法是覆盖 remove 并在调用 Backbone.View.prototype.remove 之前删除处理程序。如果您正在使用该视图,则无需手动删除您在视图的 events 属性中声明的事件。

    更具体一点,让我们依次考虑您要询问的三种类型的对象。如果您使用的是主干路由器,那么您可能正在路由器方法中创建一个视图对象,可能将其分配给一个 var,然后在页面上的某个位置设置 html。当用户离开时,将调用不同的路由器方法,并且您创建的对此视图的引用是不可访问的。假设您没有将其创建为窗口或根级别对象或类似的属性,它将被垃圾收集。

    remove 方法是关于从 DOM 中删除视图。垃圾收集器负责从内存中删除视图。 remove 方法可以方便地放置在将视图移出页面之前需要运行的任何清理代码,因此请在此处解开您的自定义事件处理程序。

    同样,model.destroy 不是要销毁存储在内存中的模型对象,而是要向服务器发送 AJAX DELETE 请求。模型对象像其他所有东西一样被垃圾收集,一旦它们无法访问就会消失。如果对模型的唯一引用包含在视图中,则删除该视图将导致模型被垃圾收集。收藏也是如此。

    最后一点,下划线绑定不是问题。它关于绑定上下文(调用函数的this 的值),而不是关于绑定事件处理程序。像往常一样删除这些事件处理程序。

    【讨论】:

    • 感谢您的回答。学习 Javascript 中的垃圾收集很不错。省去我清理未使用内存的麻烦。
    【解决方案2】:

    Model.destroy() 负责销毁服务器上的模型。是否还需要手动删除 Javascript 模型?

    Yes,还是需要手动删除模型。 Model.destroy() 不会删除它。

    类似地,我意识到 View.remove() 将从 DOM 中删除视图。应该如何安全地摆脱视图对象?

    删除所有对它的引用。如果没有任何东西指向您的对象,它将被垃圾收集。一般来说,除非您竭尽全力确保对对象的引用保持有效(例如全局变量)或对.on() 粗心,否则应该没问题。

    请注意,在您的视图中使用 .listenTo() 而不是 .on() 会让您的生活更轻松。当我们刚刚拥有.on() 时,视图的内存泄漏曾经是一个大问题(有关更多信息,请参阅here)。

    Collection.reset() 清除集合中的模型。这是否也会删除底层 Javascript 模型对象,还是需要显式删除?

    如何摆脱集合对象本身?

    Javascript 是否有垃圾收集器,它会负责删除所有此类对象吗? 只要没有对您的对象的剩余引用,它们就会被垃圾回收。

    我已经描述了这个鸟瞰图(确保你不再引用你的对象!),但是here 是一篇关于 Backbone 上下文中垃圾收集的非常好的文章。

    View.remove() 仅从 DOM 中删除视图。我的猜测是,仍然需要注意删除/销毁底层模型并取消绑定所有事件侦听器。对吗?

    请注意it also calls .stopListening(),如果您在视图中使用.listenTo(),它会取消绑定您的听众。只要没有对它的剩余引用,您就不需要删除/销毁底层模型来让它再次被 GC 处理。将 .listenTo() 与模型一起使用是对它的引用,但如果您 .remove() 您的视图将删除该引用。

    我经常使用 _.bindAll 来更改函数调用的上下文。我还没有找到解除绑定的方法。我的理解是,这是不必要的。我说的对吗?

    我不清楚你想通过“解除绑定”来达到什么目的,所以我会说没有必要。

    【讨论】:

    • 感谢您的回答。它澄清了我所有的问题。
    • 没问题!如果您对答案感到满意,请考虑接受和/或投票,以便我可以收到 SO 代表 :)
    • 我很欣赏这个答案,但我的代表人数不允许我投票。对不起!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多