Skip to content

清空数组的几种姿势

清空数组是一个高频操作:重置列表、回收旧数据、初始化组件状态,都绕不开它。JavaScript 提供了多种清空方式,但它们在语义、性能和对引用的影响上差别很大。

五种清空方式

给定以下初始数据:

js
let list = [1, 2, 3, 4, 5];
let anotherRef = list; // 另一个变量引用了同一个数组

方式一:直接赋值为空数组 list = []

js
list = [];
console.log(list); // []
console.log(anotherRef); // [1, 2, 3, 4, 5]

如果存在其他变量引用原数组,原数组并不会被清空——list 只是指向了新数组,旧数组依然完整地存在于内存中,anotherRef 依然可以访问它。这种方式适用于单引用场景:当数组只有一份引用时,将变量重新指向空数组,旧数组失去全部引用后被垃圾回收器回收。

方式二:splice 原地删除

js
list.splice(0, list.length);

splice(0, list.length) 从索引 0 开始删除 list.length 个元素,在原数组上操作,时间复杂度 O(n)。共享同一引用的其他变量也会看到空数组。

方式三:pop 循环逐个删除

js
while (list.length) {
  list.pop();
}

从尾部逐个弹出元素,时间复杂度 O(n),原地操作。每次 pop 都会触发一次数组长度变更,性能弱于 splice

方式四:shift 循环逐个删除

js
while (list.length) {
  list.shift();
}

时间复杂度 O(n²),原因是每次 shift 删除第一个元素后,后续所有元素需要向前移动一位。这是五种方式中效率最低的,不建议用于清空大数组。

方式五:直接设置 length = 0

js
list.length = 0;

这是最简洁高效的清空方式:原地操作,所有对同一数组的引用同步清空,时间复杂度 O(1)(或接近常量时间,取决于引擎实现)。在 V8 等现代引擎中,将 length 设为 0 会直接截断内部存储,不需要逐个删除元素。

选型建议

方式是否原地清空时间复杂度使用场景
list = []O(1)单引用、不关心旧数组时
splice(0, len)O(n)需要原地清空、兼容性好
while + popO(n)需要逐个处理元素
while + shiftO(n²)不推荐
length = 0~O(1)推荐,最彻底的清空

如果不需要保留对原数组的引用,list = [] 最直接。如果存在多个引用且需要同步清空,list.length = 0 是最优选择——它能保证所有引用方看到的都是空数组,同时性能表现也是最好的。