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

JavaScript嵌套数组对象数组生成时数据丢失问题排查

问题:嵌套数组的对象数组数据丢失

尝试创建包含嵌套数组的对象数组,但最后一步出现数据丢失情况,代码如下:

JavaScript代码

const args_arr = [];
const options_arr = [];
let options = '';

let text = "";
for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; j++) {
    if (i === j) {
      args_arr.push(true);
    } else {
      args_arr.push(false);
    }
  }
  text += args_arr + "<br>";
  options = {
    op1: true,
    op2: false,
    args: ['visible']
  };
  text += JSON.stringify(options) + "<br>";
  options.args.push(args_arr);
  text += JSON.stringify(options) + "<br>";
  options_arr.push(options);

  args_arr.length = 0;
}
text += '<br>' + JSON.stringify(options_arr) + "<br>";

document.getElementById("demo").innerHTML = text;

HTML代码

<pre id="demo"></pre>

运行时中间步骤输出正常,但最终options_arr里的所有对象的args数组中,visible后的子数组都变成了空数组,结果如下:

true,false,false,false,false
{"op1":true,"op2":false,"args":["visible"]}
{"op1":true,"op2":false,"args":["visible",[true,false,false,false,false]]}
false,true,false,false,false
{"op1":true,"op2":false,"args":["visible"]}
{"op1":true,"op2":false,"args":["visible",[false,true,false,false,false]]}
false,false,true,false,false
{"op1":true,"op2":false,"args":["visible"]}
{"op1":true,"op2":false,"args":["visible",[false,false,true,false,false]]}
false,false,false,true,false
{"op1":true,"op2":false,"args":["visible"]}
{"op1":true,"op2":false,"args":["visible",[false,false,false,true,false]]}
false,false,false,false,true
{"op1":true,"op2":false,"args":["visible"]}
{"op1":true,"op2":false,"args":["visible",[false,false,false,false,true]]}

[{"op1":true,"op2":false,"args":["visible",[]]},{"op1":true,"op2":false,"args":["visible",[]]},{"op1":true,"op2":false,"args":["visible",[]]},{"op1":true,"op2":false,"args":["visible",[]]},{"op1":true,"op2":false,"args":["visible",[]]}]

问题原因

这是引用类型的共享引用导致的问题:

  • 全程复用同一个args_arr数组,每次执行options.args.push(args_arr)时,并没有复制数组内容,而是把这个数组的内存引用塞进了options.args里。
  • 循环最后执行args_arr.length = 0清空数组时,所有已经推入options_arr的options对象里的args子数组,因为指向同一个args_arr引用,所以都会跟着变成空数组。

解决方案

有两种简单的修复方式:

方法1:每次循环创建新的args_arr

把args_arr的声明移到外层循环内部,每次循环都新建一个数组,避免共享引用:

const options_arr = [];
let options = '';

let text = "";
for (let i = 0; i < 5; i++) {
  // 每次循环新建数组
  const args_arr = [];
  for (let j = 0; j < 5; j++) {
    if (i === j) {
      args_arr.push(true);
    } else {
      args_arr.push(false);
    }
  }
  text += args_arr + "<br>";
  options = {
    op1: true,
    op2: false,
    args: ['visible']
  };
  text += JSON.stringify(options) + "<br>";
  options.args.push(args_arr);
  text += JSON.stringify(options) + "<br>";
  options_arr.push(options);
}
text += '<br>' + JSON.stringify(options_arr) + "<br>";

document.getElementById("demo").innerHTML = text;

方法2:推入数组的副本而非引用

在options.args.push时,传入args_arr的副本,后续修改原数组不会影响副本:

const args_arr = [];
const options_arr = [];
let options = '';

let text = "";
for (let i = 0; i < 5; i++) {
  for (let j = 0; j < 5; j++) {
    if (i === j) {
      args_arr.push(true);
    } else {
      args_arr.push(false);
    }
  }
  text += args_arr + "<br>";
  options = {
    op1: true,
    op2: false,
    args: ['visible']
  };
  text += JSON.stringify(options) + "<br>";
  // 推入数组副本,用扩展运算符或者slice()都可以
  options.args.push([...args_arr]);
  // 或者 options.args.push(args_arr.slice());
  text += JSON.stringify(options) + "<br>";
  options_arr.push(options);

  args_arr.length = 0;
}
text += '<br>' + JSON.stringify(options_arr) + "<br>";

document.getElementById("demo").innerHTML = text;

两种方法都能让options_arr里的每个对象保留正确的嵌套数组数据。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.04 00:32:53