使用array.push()时已推入对象被覆盖的问题及对象拆分需求
对象拆分时数组元素被覆盖的原因及解决方法
问题原因
JavaScript里对象属于引用类型,你代码中直接修改skus[i]的属性(比如wh、f_qty),然后把skus[i]推入数组——两次推入的其实是同一个对象的内存引用。当你第二次修改skus[i]的属性时,数组里第一个元素因为指向同一个对象,属性值自然会被覆盖。
看你的代码,处理wh1和wh2时都是直接操作原对象skus[i],没有创建新对象,导致数组里两个元素指向同一个原对象,最终显示的都是最后一次修改后的结果。
解决方法
核心思路:每次拆分时创建原对象的副本,修改副本属性后再推入数组,避免操作同一个引用。
创建对象副本常用三种方式:
- 对象扩展运算符
{...obj} Object.assign({}, obj)- 手动复制需要的属性(适合只保留部分属性的场景)
重构后的代码示例
var obj_array = []; for (var i = skus.length - 1; i >= 0; i--) { if (skus[i].id === 25) { // 处理wh1 if (skus[i].wh1.trim() !== '') { const wh1Arr = skus[i].wh1.trim().split('-'); // 创建原对象的浅拷贝 const wh1Obj = {...skus[i]}; if (wh1Arr.length === 3) { wh1Obj.wh = `${wh1Arr[0]}-${wh1Arr[1]}`; wh1Obj.f_qty = parseInt(wh1Arr[2], 10); // 转成数字类型更规范 } else { wh1Obj.wh = skus[i].wh1.trim(); wh1Obj.f_qty = skus[i].e_qty; } // 删除不需要的属性(可选,按需调整) delete wh1Obj.wh1; delete wh1Obj.wh2; delete wh1Obj.e_qty; obj_array.push(wh1Obj); } // 处理wh2 if (skus[i].wh2.trim() !== '') { const wh2Arr = skus[i].wh2.trim().split('-'); // 创建原对象的浅拷贝 const wh2Obj = {...skus[i]}; if (wh2Arr.length === 3) { wh2Obj.wh = `${wh2Arr[0]}-${wh2Arr[1]}`; wh2Obj.f_qty = parseInt(wh2Arr[2], 10); } else { wh2Obj.wh = skus[i].wh2.trim(); wh2Obj.f_qty = skus[i].e_qty; } // 删除不需要的属性 delete wh2Obj.wh1; delete wh2Obj.wh2; delete wh2Obj.e_qty; obj_array.push(wh2Obj); } } }
代码说明
- 每次处理仓库字段时,用
{...skus[i]}创建原对象的浅拷贝,修改副本属性不会影响原对象和数组中已有的元素 - 用
trim()处理仓库字符串的空格,避免拆分后出现无效元素 - 将
f_qty转为数字类型,匹配预期结果的数据格式 - 可选删除冗余属性,让结果对象结构更贴近需求
验证结果
运行上述代码后,obj_array中的两个对象是完全独立的,属性值不会互相覆盖,最终结果与预期一致:
[ {"item": "FUZZY NEKO CAT LITTER 10L","size": "10L","e_total": 23992.81,"price": 178,"wh": "WH-A","f_qty": 2,"id": 25}, {"item": "FUZZY NEKO CAT LITTER 10L","size": "10L","e_total": 23992.81,"price": 178,"wh": "WH-C","f_qty": 135,"id": 25} ]
内容的提问来源于stack exchange,提问作者melvnberd
相关产品推荐
相关产品推荐

