You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何使用扩展语法(spread syntax)克隆数组时空槽会被替换为undefined?

数组克隆时空槽变undefined的原因及解决办法

你遇到的情况是:用扩展语法[...arr]克隆包含空槽的稀疏数组时,原数组里的空槽会被替换成undefined,而非保留空槽状态。这是由JavaScript扩展语法的遍历逻辑决定的:

核心原因

JavaScript里的数组空槽(稀疏数组的空位)和undefined是完全不同的概念:

  • 空槽:数组在该索引位置没有任何元素,调用arr.hasOwnProperty(index)会返回false
  • undefined:是一个实际存在的元素值,arr.hasOwnProperty(index)返回true

扩展语法[...arr]、Array.from()以及map、filter这类数组方法,在遍历数组时会把空槽当作undefined处理——它们会为每个索引位置都添加一个元素,空槽对应的位置就被填充为undefined,最终得到的是一个“密集数组”,而非原有的稀疏数组。

你可以用这段代码直观验证两者的区别:

const arr = [1, , undefined];
// 原数组的空槽(索引1)没有自有属性
console.log(arr.hasOwnProperty(1)); // false
// 索引2是实际存在的undefined元素
console.log(arr.hasOwnProperty(2)); // true

const clone = [...arr];
// 克隆后索引1变成了实际的undefined元素
console.log(clone.hasOwnProperty(1)); // true
console.log(clone.hasOwnProperty(2)); // true

保留空槽的克隆方法

如果需要克隆数组并保留原有的空槽,可以用以下几种方法:

1. 使用Array.prototype.slice()

slice是专为数组设计的克隆方法,会完整保留稀疏数组的空槽:

const arr = [1, "", , null, undefined, false, , 0];
const clone = arr.slice();
console.log(clone); // 空槽与原数组完全一致

2. 手动创建数组并赋值

通过遍历原数组索引,仅对存在自有属性的索引赋值:

const arr = [1, "", , null, undefined, false, , 0];
const clone = new Array(arr.length);
for (let i = 0; i < arr.length; i++) {
  if (arr.hasOwnProperty(i)) {
    clone[i] = arr[i];
  }
}
console.log(clone); // 空槽被保留

3. 使用Object.assign()

Object.assign会按对象的自有属性复制,因此也能保留数组空槽:

const arr = [1, "", , null, undefined, false, , 0];
const clone = Object.assign([], arr);
console.log(clone); // 空槽保留

内容的提问来源于stack exchange,提问作者DecPK

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 16:25:22