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

JS遍历数组push对象时所有元素均为最后一个值的问题

问题根因

JavaScript里对象是引用类型,你整个循环过程中一直在反复修改同一个this.productToShowOnView对象的属性,每次往productsInBasket数组里push的都是这个对象的内存地址,不是独立的新对象。等循环执行完,this.productToShowOnView的属性已经被最后一条遍历的商品数据覆盖,数组里所有存了这个对象引用的条目,自然全显示最后一条的4份糖块数据。

另外你代码里还有两处无效逻辑:

  • const newBasket = this.productsInBasket;拿到的是原数组本身的引用,后面的[...newBasket]展开操作只是浅拷贝了数组壳,数组里存的对象引用一点没变,解决不了问题
  • this.cd.detectChanges()放在循环内每次遍历都触发,完全没必要,只会增加不必要的性能消耗
修复代码

每次循环时为当前商品创建一个独立的新对象,不要全程复用同一个productToShowOnView对象存所有条目数据,循环全部跑完再触发一次变更检测即可:

for (let bill of dataOfBillHeader.billBodies) {
  console.log(dataOfBillHeader)
  // 每次循环生成独立的新对象,切断引用关联
  const currentProduct = {
    cipher: bill.product.cipher,
    name: bill.product.name,
    measure: bill.product.measure,
    price: bill.product.price,
    id: dataOfBillHeader.id,
    // 原代码先后给count赋了bill.product.count、bill.count两个值,后者会覆盖前者,这里保留你原本的赋值逻辑
    count: bill.count,
    quantity: bill.quantity,
    discount: bill.discount,
    discountAmount: bill.discountAmount,
    totalPrice: bill.totalPrice
  }

  // 如果视图绑定需要用到this.productToShowOnView,这里做一次浅拷贝赋值即可
  this.productToShowOnView = {...currentProduct}
  console.log("to show on view is " + JSON.stringify(this.productToShowOnView));
  
  this.productsInBasket.push(currentProduct);
}
// 所有数据处理完统一触发一次变更检测
this.cd.detectChanges();
避坑提示
  • 所有往数组里存对象的场景,只要需要保留多条独立数据,就不能复用同一个对象反复修改属性后push,必须每次新建对象或者做深/浅拷贝生成独立副本
  • 数组浅拷贝只会复制数组本身,不会复制数组里存的引用类型对象,不要以为做了[...arr]操作就解决了对象引用的问题

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 14:06:26