JavaScript数组清空后,之前引用的数组元素为何仍可访问?
你最开始的判断是完全正确的:JavaScript 中对象(包括普通对象、数组、函数等)属于引用类型,赋值操作传递的是对象在堆内存中的地址引用,而非对象本身的深拷贝。
我们可以拆解你的代码执行的完整逻辑,就能明白清空数组后fullName仍然可用的原因:
- 执行
let fullNames = [{ name: "Name", surname: "Surname" }];时:- 堆内存中创建普通对象
{name: "Name", surname: "Surname"},假设它的内存地址标记为#001 - 堆内存中创建数组对象,数组的第0位存储的值是刚才的地址
#001,数组本身的内存地址标记为#002 - 栈内存的变量
fullNames存储的是数组的地址#002
- 堆内存中创建普通对象
- 执行
let fullName = fullNames[0];时:
直接把数组第0位存储的地址#001赋值给变量fullName,此时fullName直接指向了最开始创建的普通对象,和fullNames数组不存在直接绑定关系 - 执行
fullNames.length = 0;时:
仅清空了地址为#002的数组内部存储的所有引用,相当于把数组这个容器的内容全部清除,但这个操作既不会修改fullName变量存储的地址,也不会影响堆内存中地址为#001的普通对象本身 - 打印输出时自然会得到空数组、以及仍指向原对象的
fullName的结果
补充说明:JavaScript 采用引用计数的方式标记可回收垃圾,只要还有一个处于存活状态的变量持有对象的引用,这个对象就不会被垃圾回收机制销毁,因此哪怕数组被清空,只要fullName还在作用域范围内,它指向的对象就会一直存在,可以正常访问。
内容的提问来源于stack exchange,提问作者Al3ksandre
相关产品推荐
相关产品推荐

