JavaScript垃圾回收机制疑问:子对象仍被引用时父对象是否会被回收?
JavaScript垃圾回收机制疑问:子对象仍被引用时父对象是否会被回收?
哈哈,这个问题问得特别到位,刚好能帮你吃透JS垃圾回收的核心逻辑——可达性判定规则。
先给你一句话总结结论:父对象和subObjA会被垃圾回收,只有subObjB会保留下来。
咱们结合你的代码一步步拆解:
var parentObj = { A: { subObjA: 'data' }, B: { subObjB: 'data' } }; var persist = parentObj.B; parentObj = null;
JS的垃圾回收器就像个精明的清洁工,它只会清理那些完全找不到访问路径的对象——也就是从全局变量、当前执行上下文的变量等“根节点”出发,顺着引用链找不到的对象。
- 当你执行
var persist = parentObj.B时,相当于给subObjB多绑了一根“绳子”:原来只有父对象引用它,现在persist也直接引用它了,这根绳子让subObjB始终处于“可被找到”的状态。 - 而
parentObj = null这一步,直接剪断了指向父对象的唯一“顶层绳子”——现在没有任何变量再直接指向父对象了。
接下来看各个对象的命运:
- subObjB:因为
persist还牢牢指着它,从当前作用域的根节点能顺着引用找到它,所以它是可达的,不会被回收。 - 父对象本身:现在没有任何变量直接引用它,虽然它曾经引用过
subObjB,但subObjB并没有反过来引用它(这里没有循环引用),所以父对象完全变成了“无主”状态,会被垃圾回收器清理。 - subObjA:它只被父对象引用,而父对象已经不可达了,所以
subObjA也没有任何能被找到的路径,会跟着父对象一起被回收。
至于你问的“是否需要显式清理”——完全没必要!JS的垃圾回收器会自动识别并清理这些不可达的对象,你不用手动去delete子元素或者父对象,只要确保不再保留多余的引用就行。
备注:内容来源于stack exchange,提问作者Voldrix
相关产品推荐
相关产品推荐

