setTimeout匿名回调函数在计时期间的存储位置问询
关于setTimeout匿名函数存储位置的解答
核心结论
当你调用setTimeout传入匿名函数时,这个函数并不会被垃圾回收——浏览器的Web API(定时器模块)会持有它的引用,直到计时结束后将其推入任务队列等待执行。
具体执行流程拆解
结合你的代码一步步分析:
console.log("Start of the program execution!"); setTimeout(() => { console.log("I ran after a second!"); }, 1000); console.log("The end of the file!");
- 执行
setTimeout时:JS引擎会把匿名函数、1000ms延迟参数传递给浏览器的Web API定时器模块,Web API会保存这个匿名函数的引用并开始计时。 - JS引擎继续执行后续代码:调用栈依次执行
console.log("Start...")、setTimeout(仅触发Web API,本身快速执行完成)、console.log("The end..."),随后调用栈清空。 - 第5行断点看不到匿名函数的原因:此时匿名函数的引用不在全局作用域(不像具名函数
doSth存在全局内存),而是被Web API持有,所以你在全局执行上下文的Scope面板中找不到它——但它并未被销毁,垃圾回收器因Web API还持有引用,不会回收这个函数对象。 - 计时结束后的处理:1秒计时完成后,Web API会把匿名函数包装成宏任务推入任务队列。事件循环检测到调用栈为空时,会将该任务推入调用栈执行,这时候你在匿名函数内部的断点就能看到它出现在调用栈里。
和具名函数的本质区别
具名函数doSth存储在全局内存中,Web API持有的是它的引用;匿名函数则是直接将函数对象的引用交给Web API,二者本质都是引用传递,仅存储位置不同:
- 具名函数的引用在全局作用域,所以能在Scope面板中看到;
- 匿名函数的引用在Web API模块中,JS引擎当前执行上下文无法直接访问,但只要有引用存在,函数就不会被回收。
内容的提问来源于stack exchange,提问作者mukesharyal
相关产品推荐
相关产品推荐

