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进去,而不是原对象本身。给你几个常用的方法:
ES6对象展开语法(最简洁)
修改addItem方法,先拷贝对象再push:addItem : function(item){ if(this.eligible(item)){ // 用展开语法创建新的对象副本 const newItem = {...item}; this.list.push(newItem); // ... 你的其他代码 } }用
Object.assign()兼容旧环境
如果你的项目需要支持ES6之前的浏览器,用Object.assign也能实现浅拷贝:addItem : function(item){ if(this.eligible(item)){ const newItem = Object.assign({}, item); this.list.push(newItem); // ... 你的其他代码 } }手动复制属性(适合属性少的情况)
要是对象属性不多,手动复制也很稳妥: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
相关产品推荐
相关产品推荐

