如何在数组中添加对象且避免引用同一实例?
解决数组克隆后修改元素影响多个项的问题
这个问题的核心是浅拷贝导致的引用共享,我来给你拆解原因和解决办法:
首先你遇到的问题根源在于:[...chartSeriesArray]是浅拷贝——它只复制了数组本身的引用,但数组里的对象还是原来的那个引用。当你把这个克隆后的clonedArray连续push两次到x里时,x[0]和x[1]其实指向的是同一个数组对象。所以你修改x[0].foo的时候,本质上是在修改那个共享的数组,自然x[1]也会跟着变化。
解决办法:每次循环创建完全独立的数组和对象拷贝
你需要确保每次push到x里的都是全新的数组,且数组内的对象也是新的拷贝,而非复用同一个引用。这里有几种可行的方式:
方法1:用map+对象扩展运算符(适合无嵌套的简单对象)
这种方式会为数组里的每个对象创建新拷贝,同时生成全新的数组:
var chartSeriesArray = [{"EnableAnimation": true,"AnimationDuration": 1}]; let x = []; for(i=0;i<2;i++){ // 每次循环都生成新数组,且数组内的对象也是新拷贝 let clonedArray = chartSeriesArray.map(item => ({...item})); x.push(clonedArray); } x[0].foo = "bar"; console.log(x); // 输出结果: // 0: [{EnableAnimation: true, AnimationDuration: 1}, foo: "bar"] // 1: [{EnableAnimation: true, AnimationDuration: 1}]
方法2:JSON序列化实现深拷贝(适合无特殊值的对象)
如果你的对象有嵌套结构,JSON序列化可以实现深拷贝(注意:无法处理函数、undefined、Symbol等特殊类型):
var chartSeriesArray = [{"EnableAnimation": true,"AnimationDuration": 1}]; let x = []; for(i=0;i<2;i++){ let clonedArray = JSON.parse(JSON.stringify(chartSeriesArray)); x.push(clonedArray); } x[0].foo = "bar"; console.log(x);
方法3:手动递归实现深拷贝(最灵活,支持复杂对象)
如果你的对象包含函数、Symbol等JSON无法处理的类型,可以自己写一个深拷贝函数:
function deepClone(obj) { if (obj === null || typeof obj !== 'object') return obj; if (obj instanceof Array) return obj.map(item => deepClone(item)); if (typeof obj === 'object') { const newObj = {}; for (let key in obj) { if (obj.hasOwnProperty(key)) { newObj[key] = deepClone(obj[key]); } } return newObj; } } var chartSeriesArray = [{"EnableAnimation": true,"AnimationDuration": 1}]; let x = []; for(i=0;i<2;i++){ let clonedArray = deepClone(chartSeriesArray); x.push(clonedArray); } x[0].foo = "bar"; console.log(x);
总结
核心就是避免引用共享,只要保证每次添加到x里的数组都是完全独立的(包括数组内部的对象),就能实现只修改x[0]而不影响x[1]的效果。
内容的提问来源于stack exchange,提问作者Harsh
相关产品推荐
相关产品推荐

