回调函数内部声明的变量是否保留在内存中,还是在回调执行结束时销毁?
Do variables declared inside callback functions remain in memory or are they destroyed upon end of callback execution?
我有这个代码片段;它基本上连接到mongo数据库并浏览文档。在每次迭代中,它搜索对象数组的消息。它创建消息变量,然后循环遍历它。在回调函数中声明的变量(var msg
)是否保留在内存中,或者在回调函数执行结束时销毁?如果var msg
实际上被声明为let msg
,会有什么不同吗?有没有一种方法可以从内存中丢弃整个范围?
MongoClient.connect(mongoUrl, (err, db) => {
assert.equal(null,err);
var collection_data = db.collection('threadContents').find();
collection_data.on('data', (doc) => {
var msg = doc.messages;
for (var variable in msg) {
console.log(msg);
}//forin(msg)
});//collection_data.on
});//mongo.connect
理论上是的。
在实践中-这不是那么简单…
在您的示例中,var msg
不会在其原始作用域之外"泄漏",因此当回调完成它的工作时,它很可能会被销毁。
有一件事要注意——这个对象的销毁不必立即发生——JS引擎大多是垃圾收集的,所以这片内存可以在堆栈上停留一段时间,但它将不再是可访问的。
如果你在外部作用域中声明这个变量,如果这个作用域在内存中,它可能会留在内存中(所以,其他代码段可以访问该变量)。您可以在MDN的闭包部分中了解此行为。
另一个需要注意的是console.log
的使用。通常,非原语值(如对象或数组,它们实际上是"特殊"对象)可以通过引用访问,而不是通过值访问。因此,如果您的var msg
是一个非原语,那么它很可能会一直保存在内存中,直到您清空控制台。原始值将被复制,因此严格地说,它们仍然会保存在内存中,但可能会在内存的另一个地方(尽管JIT引擎可能会尝试优化这一点,并且在不必要的情况下不复制内存)。
Node.js(和所有javascript引擎)依赖于跟踪垃圾收集,这意味着已分配的内存以不确定的方式被释放,即您无法准确预测何时会发生。这通常不会影响到您,但是如果您确实希望以可预测的方式释放一些内存块或其他资源,则必须使用一些特殊的技术。
在您的特定示例中,'msg'将被删除,但不要期望它立即被删除。
- 如何在回调函数中执行流
- 如何在`window.open`之后执行回调
- 等待回调函数执行
- 带有Spring的$.getJSON未执行回调
- bookmarklet中的jQuery.getScript()进行回调,但没有成功执行插件
- Dojo AMD加载程序执行定义具有空/缺失依赖项的回调
- 不同'单击'不同脚本中的回调:我可以控制执行顺序吗
- TypeError:执行回调时,回调不是函数
- Javascript:对回调创建的对象执行方法
- AJAX成功回调-执行javascript时出现问题
- nodeJS中的承诺/承诺中的回调/执行顺序是不对的
- 主干:中止以前的路由器回调执行
- 控制器函数作为回调执行
- 函数/回调执行可以被外部调用中断吗?
- React setState回调执行序列
- 一个关于nodejs回调执行顺序问题的例子,我不能理解
- 禁用返回按钮,直到回调执行
- 回调函数内部声明的变量是否保留在内存中,还是在回调执行结束时销毁?
- 在javascript中,使用回调执行多个异步函数的最佳实践是什么?
- Javascript中的回调执行序列,从IndexeddB检索