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

array.push()重复添加相同值:自定义列表管理对象异常求助

问题分析与解决方案

嘿,这个问题我太熟了——这是JavaScript里引用类型的经典坑!你遇到的情况,本质是每次添加到数组里的都是同一个对象的引用,而不是新的对象实例。

为啥会这样?

JavaScript里的对象属于引用类型,当你把一个对象push到数组里时,数组存的不是这个对象的“副本”,而是指向它的内存地址。如果你反复修改同一个对象,然后多次push进去,数组里的所有元素其实都指向同一个内存地址,最后自然全变成最后一次修改的样子啦。

看你的代码,addItem方法直接把传入的item对象塞进数组:

addItem : function(item){ 
  if(this.eligible(item)){ 
    this.list.push(item); 
    // ... 你没写完的console代码
  } 
}

举个例子,如果你是这么调用的:

let myItem = {w: 10, h: 5, l: 3, m: 20};
list.addItem(myItem);
myItem.w = 20; // 修改同一个对象的属性
list.addItem(myItem);

那数组里的两个元素肯定都是修改后的myItem,因为它们根本就是同一个东西的不同“指针”。

怎么修复?

解决思路很简单:每次添加时,创建一个原对象的副本,把副本push进去,而不是原对象本身。给你几个常用的方法:

  1. ES6对象展开语法(最简洁)
    修改addItem方法,先拷贝对象再push:

    addItem : function(item){ 
      if(this.eligible(item)){ 
        // 用展开语法创建新的对象副本
        const newItem = {...item};
        this.list.push(newItem); 
        // ... 你的其他代码
      } 
    }
    
  2. 用Object.assign()兼容旧环境
    如果你的项目需要支持ES6之前的浏览器,用Object.assign也能实现浅拷贝:

    addItem : function(item){ 
      if(this.eligible(item)){ 
        const newItem = Object.assign({}, item);
        this.list.push(newItem); 
        // ... 你的其他代码
      } 
    }
    
  3. 手动复制属性(适合属性少的情况)
    要是对象属性不多,手动复制也很稳妥:

    addItem : function(item){ 
      if(this.eligible(item)){ 
        const newItem = {
          w: item.w,
          h: item.h,
          l: item.l,
          m: item.m
        };
        this.list.push(newItem); 
        // ... 你的其他代码
      } 
    }
    

顺便提个小优化

你的eligible方法里的逻辑可以简化一下,不用绕个弯子给status赋值:

eligible: function(item){ 
  const dw = (item.w * item.h * item.l) / 169; 
  return dw > item.m; 
}

直接返回判断结果就行,代码更清爽~

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:40:34