安全地删除和销毁主干对象

时间:2015-04-28 22:25:30

标签: backbone.js collections model reset destroy

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

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

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

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

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

2 个答案:

答案 0 :(得分:1)

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

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

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

为了更具体一点,让我们考虑一下你要问的三种对象。如果您正在使用骨干路由器,那么您可能正在路由器方法中创建一个视图对象,可能将其分配给var,然后在页面上的某处设置html。当用户导航时,将调用另一个路由器方法,并且无法访问您为此视图创建的引用。如果您没有将其创建为窗口或根级别对象上的属性或类似内容,则会收集垃圾。

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

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

对于你的最后一点,下划线绑定不会成为问题。它关于绑定上下文(调用函数的model.destroy的值),而不是绑定事件处理程序。像往常一样删除那些事件处理程序。

答案 1 :(得分:1)

  

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

Yes,您仍需要手动删除模型。 Model.destroy()不会将其删除。

  

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

删除对它的所有引用。如果没有任何东西指向你的对象,它将收集垃圾。一般来说,除非你不遗余力地确保对象的引用保持活跃(例如全局变量)或者对.on()粗心大意,否则你应该没问题。

请注意,在您的观看次数而不是.listenTo()上使用.on()会让您的生活更轻松。当我们只有.on()时,内存泄漏,视图曾经是一个大问题(更多信息见here)。

  

Collection.reset()清除集合中的模型。这还会删除基础Javascript模型对象还是需要明确删除它们?

     

如何摆脱集合对象本身?

     

Javascript是否有垃圾收集器,是否会删除所有这些对象?   只要没有对您的对象的剩余引用,他们就会收集垃圾。

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

  

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

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

  

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

我不清楚你想通过"取消绑定,"所以我会说这没有必要。