通过for循环扩充数组仅保留最后一个对象?附数据与模板示例
为啥for循环扩充数组只留最后一个对象?
嘿,这个坑我之前也踩过!十有八九是你在循环里重复复用了同一个对象的引用,没每次都创建新的独立对象导致的~
问题根源
JavaScript里的对象是引用类型,意思是当你把一个对象赋值给变量或者push进数组时,其实存的不是对象本身,而是指向这个对象的内存地址。如果你的循环逻辑是这样的:
let result = []; // 直接修改原template对象然后push for (let student of data) { template.name = student.name; template.x = student.grades.length; // 假设x是成绩数组长度 result.push(template); }
那数组result里的每一项,其实都指向同一个template对象。循环到最后,template的属性被最后一个学生的数据覆盖了,所以你打印数组时,所有元素看起来都是最后一个对象的内容。
解决办法:每次循环创建新对象
我们需要在每次循环里,基于template生成一个新的对象实例,这样每个数组元素都是独立的,不会互相影响。这里给你几种常用的写法:
方法1:对象展开运算符(最简洁)
用...展开template的所有属性,再覆盖需要修改的字段:
let result = []; for (let student of data) { const newItem = { ...template, // 复制template的所有属性 name: student.name, // 替换name x: student.grades.length // 设置x的值 }; result.push(newItem); }
方法2:Object.assign()
用Object.assign()把template的属性拷贝到新的空对象里,再添加自定义属性:
let result = []; for (let student of data) { const newItem = Object.assign({}, template, { name: student.name, x: student.grades.length }); result.push(newItem); }
注意:如果template有嵌套对象
如果你的template里还有嵌套的对象(比如grades: []这种),上面的浅拷贝就不够了,需要用深拷贝。简单的深拷贝可以用JSON.parse(JSON.stringify(template)),但要注意它不能处理函数、日期这类特殊类型:
let result = []; for (let student of data) { // 深拷贝template const newItem = JSON.parse(JSON.stringify(template)); newItem.name = student.name; newItem.x = student.grades.length; result.push(newItem); }
总结
核心就是:不要在循环里修改同一个对象然后重复push,一定要每次都生成新的对象实例,这样数组里的每个元素才会保存对应循环迭代的内容~
内容的提问来源于stack exchange,提问作者Hugo LOPEZ
相关产品推荐
相关产品推荐

