我有这个代码片段;它基本上连接到 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 引擎大多是垃圾收集的,因此这 block 内存可以在堆栈上保留一段时间,但将不再可访问。
如果您要在外部作用域中声明此变量,并且该作用域保留在内存中,则它可能会保留在内存中(因此,其他代码片段可以访问该变量)。您可以在Closures中阅读有关此行为的信息。 MDN 部分。
另一件事需要注意的是console.log
的使用。一般来说,非原始值(例如对象或数组,它们实际上是“特殊”对象)可以通过引用而不是值来访问。因此,如果您的 var msg
是非基元,它很可能会保留在内存中,直到您清除控制台。原始值将被复制,因此严格来说,它们仍然会保留在内存中,但可能会保留在内存中的另一个位置(尽管 JIT 引擎可能会尝试优化它,并且如果不需要,则不会复制内存)。
关于javascript - 回调函数内声明的变量是否保留在内存中,还是在回调执行结束时被销毁?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39306225/