setTimeout是否会阻止函数被垃圾回收?

3
假设我有以下myFunctionsetTimeout的组合:
function myFunction(){
    var am_i_eaten = 'ffdfjdhsfhs';

    setTimeout(function(){
        console.log(am_i_eaten);
    },3000);
}

myFunction();
< p >setTimeout函数会保留myFunction的作用域(因为它可以毫无问题地打印am_i_eaten),并防止在Node.JS环境中被垃圾回收。我相信这种行为与浏览器中的行为有些不同?< /p > < p >谢谢!< /p >

闭包中的变量将在 setTimeout 调用后被 GC 回收,除非 GC 真的很聪明并且你有一些其他变量在超时函数中不可引用(即没有使用标识符,没有 eval),在这种情况下,那个其他变量可能会被 GC 回收。不过不要依赖于“聪明”的部分,如果你担心,完成后将标识符设置为 null - Paul S.
嗨,感谢您的回复!那么通过将标识符设置为null,您是指我应该在函数末尾,在setTimeout之后只需执行am_i_eaten = null吗? - josh
不,我的意思是如果你有第二个变量,在timeout的函数中没有使用,因此对于timeout来说并不是必要的,例如 var foo = ["some", "big", "memory", "hog"];..在完成_foo_后,foo = null; - Paul S.
@PaulS。啊,我明白了。但是,如果我根本不想让setTimeout一直保持函数的作用域呢?我想把所有变量或引用都传递给setTimeout,但仍然要进行垃圾回收功能?我可以将setTimeout包装在一个匿名函数中吗? - josh
为了保证回调函数的行为,需要从函数闭包外部引用它,如果你想传递任何变量到其中,那么你可能需要一个生成器函数。setTimeout的第三个及以上参数被定义为回调函数的参数,但许多实现并不包括该功能(我不知道在node.js中是否有)。在某些时候,你需要问自己是否额外函数调用的开销值得更早的垃圾回收 :) - Paul S.
@PaulS。明白了,非常感谢您抽出时间回复。我想我会在函数结束时将所有不再使用的标识符设置为“null”。 - josh
3个回答

2
你创建的是一个函数闭包,该闭包中的变量在 setTimeout() 回调运行之后才会被垃圾回收。你可以将函数的局部变量概念化为单独的项目,只有当没有其他可调用的代码可以访问这些变量时,它们才会被垃圾回收。因此,在 setTimeout() 回调运行之前,变量 am_i_eaten 仍然可以访问,不会被垃圾回收。这在浏览器和 node.js 中的工作方式完全相同(Chrome 和 node.js 中使用的是相同的 V8 JS 引擎)。

此外,在Chrome上使用repl进行测试似乎与jfriend00所说的一致。https://repl.it/@DanielKaspo/GrizzledOrchidJavadocs - NessDan
@PauliSudarshanTerho - 我把第二个改成了与第一个相同的措辞。它们应该意味着相同的事情。 - jfriend00
@PauliSudarshanTerho - 我不确定你所说的“全局上下文”是什么意思。许多异步回调函数无法从全局上下文中访问。这些回调函数内部的变量只能从回调函数本身中访问 - 它们无法从在全局上下文中运行的代码中访问。 - jfriend00
啊..我的意思是“全局对象”- 该算法假定已知一组称为根的对象。在JavaScript中,根是*全局对象...从根开始,垃圾收集器将找到所有可达对象并收集所有不可达对象。* ... 标记和清除算法:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Memory_Management#Mark-and-sweep_algorithm - user985399
如果我没记错的话,全局对象是window对象。变量am_i_eaten可以从window访问,因为它没有被收集。据说在Javascript中不可能有秘密变量,但也许我们在几秒钟内就会拥有它? - user985399
显示剩余2条评论

1

setTimeout的任意数据在timeout操作完成后会被垃圾收集器自动清除。


0
在JavaScript中,函数的作用域是在函数创建时创建的。setTimeout接受一个回调函数,该函数保留了myFunction的作用域引用。因此,在回调函数被调用之前,它不会被垃圾回收。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接