7

我正在学习 node.js,并且注意到几乎所有回调都作为匿名回调内联到函数中。以这种方式做事背后有特定的原因吗?

我认为使用命名回调并将其定义为本地函数有两个优点: 1. 它更简洁,并且不会将函数变成一个巨大的代码块 2. 给定适当的名称,它充当文档 - 描述什么回调应该做

4

1 回答 1

6

当在全局作用域中使用命名函数作为回调时,函数命名的作用域可能会导致函数在内存中持久化并阻止它被垃圾回收。这是导致应用程序内存泄漏的众多方法之一。另一方面,匿名函数在执行结束后立即标记为 GC,并且任何未返回的内容(也可能是闭包)将自动标记为垃圾回收。

考虑一个相当复杂的 jQuery 插件。在生成和返回作为插件主题的实际对象之前,它可能必须创建数十个保存临时状态数据的变量。如果这不是在 IIFE(立即调用的函数表达式:立即执行的匿名函数)中完成的,这些变量将“泄漏”到全局范围内。只要有任何一个变量或闭包仍在引用它,JavaScript 中的数据就会保留在内存中。由于这些变量已“泄漏”到全局范围,因此它们将保留在内存中,直到该选项卡/窗口关闭。在 IIFE 中定义时,定义的变量会停留在本地匿名函数的范围内。因此,当函数完成执行时,变量“消失” 他们的数据不再有任何参考。JS 引擎的垃圾收集器注意到内存中的这些特定数据不再被任何地方引用,并将其标记为删除,从而释放占用的内存以供其他数据使用。

因此,如果您为函数命名并且只调用它们一次,它们可能会不必要地占用内存。使它们匿名将在执行后回收内存,从而减少应用程序的内存开销。

这本质上是对大多数动态语言如何工作的描述,以及为什么它们比 C 等静态语言更受欢迎,你必须跟踪你所做的每个内存分配,并确保在不再需要时删除它们它们(本身就是一个练习;决定您需要多长时间的特定数据并不总是微不足道的)。

于 2013-06-14T05:29:54.233 回答