
本文详解为何在循环中向对象嵌套数组 push 同一数组引用会导致最终数据清空,并通过展开运算符实现安全的浅拷贝,确保每次迭代保存独立副本。
本文详解为何在循环中向对象嵌套数组 push 同一数组引用会导致最终数据清空,并通过展开运算符实现安全的浅拷贝,确保每次迭代保存独立副本。
在 JavaScript 中,数组是引用类型。当你执行 options.args.push(args_arr) 时,实际压入的是对 args_arr 这个同一内存地址的引用,而非其当前内容的副本。随后调用 args_arr.length = 0 清空数组,会直接影响所有已存入 options.args(乃至 options_arr)中的该引用——因为它们指向同一个数组对象。
因此,尽管每次循环中 JSON.stringify(options) 显示正常(此时 args_arr 尚未被清空),但当循环结束、args_arr 被反复重置为空数组后,options_arr 中所有对象的 args[1] 项都指向这个已被清空的数组,最终 JSON.stringify(options_arr) 输出全是 ["visible",[]]。
✅ 正确做法是:在 push 前创建 args_arr 的独立副本。推荐使用展开运算符(spread syntax)实现浅拷贝:
options.args.push([...args_arr]); // ✅ 创建新数组,保留当前值
完整修正后的代码如下(关键修改已高亮):
const args_arr = [];
const options_arr = [];
let text = "";
for (let i = 0; i ";
const 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;
⚠️ 注意事项:
-
...args_arr仅执行一层浅拷贝,适用于本例中args_arr元素均为原始值(布尔型)的场景; - 若
args_arr内部包含对象或嵌套数组,需使用structuredClone()(现代环境)或递归深拷贝方案; - 避免复用同一数组实例进行多次
push引用——这是引发“数据神秘消失”的常见陷阱。
总结:理解引用 vs 值、在必要时显式拷贝,是编写健壮 JavaScript 数据结构的关键基础。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











