为何JavaScript按引用复制对象时垃圾回收机制表现如此?
为什么JavaScript中修改引用变量后原对象还能被访问?
这问题问得太关键了——很多刚接触JS引用类型的开发者都会在这里卡壳,我用大白话给你捋明白:
首先得搞懂变量和对象的本质关系:
你创建的{ name: 'John' }是一个实实在在的对象,存放在内存里;而user和admin这些变量,本质上是指向这个内存地址的引用指针,不是对象本身。
第一个例子的逻辑
let user = { name: 'John' }; let admin = user; admin.name = 'Pete'; // 通过"admin"引用修改 alert(user.name); // 'Pete', 从"user"引用可见修改
这里admin = user做的事情,是把user手里的“地址纸条”复制了一份给admin——现在两个人手里的纸条都指向同一个对象。所以不管谁去修改这个对象的属性,另一个人看到的都是修改后的结果,因为他们找的是同一个东西。
第二个例子的核心差异
let user = { name: 'John' }; let admin = user; user = null; console.log(user); // 返回null console.log(admin);// 返回{name: "John"}
当你执行user = null时,你只是把user手里的“地址纸条”换成了一张写着null的废纸——也就是说user不再指向原来的对象了,但admin手里的地址纸条还好好的,依然指向那个对象。
垃圾回收机制的判断逻辑
JS的垃圾回收器是靠可达性来干活的:只要有至少一个有效引用还指着某个对象,这个对象就被认为是“有用的”,不会被回收。
在第二个例子里,admin还在引用原对象,所以这个对象依然是可达的,自然不会被回收。只有当你把admin也设为null(或者让admin指向其他东西),这个对象才会彻底失去所有引用,垃圾回收器才会在合适的时机把它从内存里清除掉。
内容的提问来源于stack exchange,提问作者user3162865
相关产品推荐
相关产品推荐

