
本文详解为何在 foreach 循环中复用同一对象引用会导致所有元素值被覆盖,并提供基于对象深拷贝与即时构造的两种可靠解决方案。
本文详解为何在 foreach 循环中复用同一对象引用会导致所有元素值被覆盖,并提供基于对象深拷贝与即时构造的两种可靠解决方案。
在 javaScript 中,对象是引用类型。当你在循环外定义一个对象(如 aSeries = { name: ”, data: [{}] }),然后在每次迭代中仅修改其属性(如 aSeries.name = element)并推入数组,实际上你只是将同一个对象的多个引用压入了 seriesArray。最终数组中所有元素都指向内存中的同一对象实例——因此最后一次赋值(name: ‘incline’)会覆盖之前所有修改,导致输出中两个对象的 name 均为 “incline”。
✅ 正确做法是:每次迭代都创建一个全新的、独立的对象实例。以下是推荐实现:
const seriesTitles = ['depth', 'incline']; const seriesArray = []; seriesTitles.forEach(element => { // ✅ 每次迭代都新建对象 —— 真正的独立副本 const aSeries = { name: element, data: [{}] }; seriesArray.push(aSeries); }); console.log(seriesArray); // 输出: // [ // { name: "depth", data: [{}] }, // { name: "incline", data: [{}] } // ]
? 进阶建议:
- 使用 map() 更语义化地表达“将数组转换为新对象数组”的意图:
const seriesArray = seriesTitles.map(title => ({ name: title, data: [{}] })); - 若 data 结构需动态填充 json 数据(如从 API 获取),可直接内联解析:
const jsonData = [{ x: 0, y: 10 }, { x: 1, y: 20 }]; const seriesArray = seriesTitles.map(title => ({ name: title, data: jsonData // 或 JSON.parse(jsonString) }));
⚠️ 注意事项:
立即学习“Java免费学习笔记(深入)”;
- 避免在循环外声明对象后在循环内复用——这是引发“所有项相同”的最常见陷阱;
- Object.assign({}, aSeries) 或展开运算符 {…aSeries} 仅适用于浅拷贝;本例中 data: [{}] 是简单嵌套,但若 data 含多层对象,需考虑 structuredClone()(现代环境)或深拷贝库;
- 始终优先使用 const 声明循环内变量,强化不可变意识,减少意外重赋值风险。
总结:对象引用本质决定了“复用即共享”。构建独立数据结构时,务必确保每次迭代都执行 new Object()、对象字面量 {} 或等效构造逻辑——这是 javascript 动态数据组装的基石原则。