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

JavaScript新手疑问:数组对象复制后重置索引/order值异常

JavaScript对象数组重置index/order异常问题解析

问题描述

我有一个包含对象的数组,每个对象包含index(数组索引)、order(索引+1)和name(文本值)三个属性。初始数组如下:

var arrayOfObjects = [
  {
    index:0,
    order:1,
    name:"Some name"
  },
  {
    index:1,
    order:2,
    name:"Some other name"
  }
];

我编写了duplicateObject函数,将数组第一个对象复制到数组开头:

function duplicateObject (){
  arrayOfObjects.splice(0,0,arrayOfObjects[0]);
}

执行后数组状态符合预期:

var arrayOfObjects = [
  {
    index:0,
    order:1,
    name:"Some name"
  },
  {
    index:0,
    order:1,
    name:"Some name"
  },
  {
    index:1,
    order:2,
    name:"Some other name"
  }
];

接着编写resetNumbers函数遍历数组,重置每个对象的index和order,并在duplicateObject中调用它:

function resetNumbers (){
  for (let i=0; i < arrayOfObjects.length; i++){
    arrayOfObjects[i].index = i;
    arrayOfObjects[i].order = i + 1;
  }
  console.log(arrayOfObjects);
}

我预期重置后的数组应为:

var arrayOfObjects = [
  {
    index:0,
    order:1,
    name:"Some name"
  },
  {
    index:1,
    order:2,
    name:"Some name"
  },
  {
    index:2,
    order:3,
    name:"Some other name"
  }
];

但实际得到的结果却是:

var arrayOfObjects = [
  {
    index:0,
    order:2,
    name:"Some name"
  },
  {
    index:0,
    order:2,
    name:"Some name"
  },
  {
    index:1,
    order:3,
    name:"Some other name"
  }
];

完整代码如下:

var arrayOfObjects = [{
    index: 0,
    order: 1,
    name: "Some name"
  },
  {
    index: 1,
    order: 2,
    name: "Some other name"
  }
];

function resetNumbers() {
  for (let i = 0; i < arrayOfObjects.length; i++) {
    arrayOfObjects[i].index = i;
    arrayOfObjects[i].order = i + 1;
  }
  console.log(arrayOfObjects);
}

function duplicateObject() {
  arrayOfObjects.splice(0, 0, arrayOfObjects[0]);
  resetNumbers();
}

//start the code
duplicateObject();

问题原因

核心问题在于JavaScript中对象是引用类型:

  • 执行arrayOfObjects.splice(0,0,arrayOfObjects[0])时,并没有复制新对象,而是将原数组第一个对象的引用插入到数组开头。此时数组第0位和第1位指向的是内存中同一个对象。
  • 在resetNumbers循环中:
    1. 当i=0时,修改第0位对象的index为0、order为1,第1位的对象(同一个引用)会同步更新。
    2. 当i=1时,修改第1位对象的index为1、order为2,这会覆盖之前的设置,导致第0位和第1位的对象同时变成index:1, order:2。
    3. 最终输出的结果中前两个对象属性一致,就是因为它们本质是同一个对象,后续修改会互相覆盖。

解决方案

要解决这个问题,需要复制原对象的独立副本而非直接引用,确保插入的是新对象。可以通过以下两种方式实现:

方法1:使用展开运算符...

修改duplicateObject函数:

function duplicateObject (){
  // 复制原对象的所有属性到新对象
  const newObj = {...arrayOfObjects[0]};
  arrayOfObjects.splice(0,0,newObj);
}

方法2:使用Object.assign()

function duplicateObject (){
  const newObj = Object.assign({}, arrayOfObjects[0]);
  arrayOfObjects.splice(0,0,newObj);
}

这样插入的是独立的新对象,后续修改不会互相影响,执行resetNumbers后就能得到预期的结果。


内容的提问来源于stack exchange,提问作者Amin Abu Dahab

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.17 08:15:43