JavaScript中销毁类实例失败,将实例赋值为null/undefined为何不生效?
核心原因
JavaScript 的参数传递规则决定了你这种写法不可能修改外层的avatar2变量:
对于对象类型的参数,函数接收的是引用的副本,不是原始引用本身。你在destroy方法中执行target = undefined,修改的只是destroy函数作用域内的局部变量target,完全不会影响到外层作用域里的avatar2变量,它仍然指向原来的类实例,所以自然不会被删除。
具体原理拆解
- 你执行
avatar.destroy(avatar2)时,首先会把avatar2存储的「实例内存地址」复制一份,传给destroy的形参target,此时target和外层的avatar2指向同一个实例,但两个是完全独立的变量 - 方法内的赋值操作只会切断
target和实例的关联,外层avatar2和实例的关联还完全存在,实例自然不会被垃圾回收机制清理
正确实现销毁的方案
要让实例被回收,只需要切断所有指向它的引用即可,你直接在外层给变量赋值就行,不需要封装到类方法里:
// 直接修改外层变量即可 avatar2 = null
如果一定要封装成方法,需要把目标变量放在一个容器对象里传入,才能修改容器内的属性:
class Avatar{ constructor(name, weapon = "knife", pv = 100){ this.name = name; this.weapon = weapon; this.pv = pv; } attaqueDefault(target){ if (target.hasOwnProperty('pv')) target.pv -= 20; } attaqueCombine(target){ if (target.hasOwnProperty('pv')) target.pv -= 35; } destroy(container, key){ container[key] = null } } var avatar = new Avatar("tchod"); // 把实例存在对象容器里 const container = { avatar2: new Avatar("tchod2", ".44") } avatar.destroy(container, 'avatar2'); // 此时container.avatar2已经为null,没有其他引用的话实例会被自动回收
内容的提问来源于stack exchange,提问作者alexis wandor
相关产品推荐
相关产品推荐

