求助:JavaScript代码中数组对象重复问题的排查与解决
问题描述
尝试用JSON对象创建数组时,数组内最后一个对象出现重复情况,相关代码、实际输出及期望输出如下:
代码
let list = [ { 'title':'alfa', 'item':'box', 'count':2 }, { 'title':'beta', 'item':'ball', 'count':4 } ] let ev = {} let ev_arr = [] for(let i in list){ ev.title = list[i].title ev.item = list[i].item ev_arr.push(ev) } console.log(ev_arr)
实际输出
[ { 'title':'beta', 'item':'ball' }, { 'title':'beta', 'item':'ball' } ]
期望输出
[ { 'title':'beta', 'item':'ball' }, { 'title':'alfa', 'item':'box' } ]
问题原因
- 对象引用重复:仅创建了一个
ev对象,循环中每次修改的都是该对象的属性,随后将同一个对象的引用推入数组。数组中的两个元素实际指向内存中同一个对象,因此最后一次修改会覆盖之前的内容,导致输出全部为最后一个对象。 - 遍历顺序问题:
for...in遍历数组时会按索引顺序(0到1)处理元素,先处理alfa再处理beta,但由于对象引用的问题,最终数组元素均为最后修改的beta对象;而期望输出顺序是先beta后alfa,还需调整遍历或数组顺序。
解决方案
方案一:循环内创建新对象+反转数组
将ev = {}放入循环内部,每次迭代生成新对象,避免引用复用;最后反转数组得到期望顺序:
let list = [ { 'title':'alfa', 'item':'box', 'count':2 }, { 'title':'beta', 'item':'ball', 'count':4 } ] let ev_arr = [] for(let i in list){ let ev = {} // 每次循环创建新对象 ev.title = list[i].title ev.item = list[i].item ev_arr.push(ev) } ev_arr.reverse() // 反转数组调整顺序 console.log(ev_arr)
方案二:使用map方法+反转数组
map方法会自动生成新数组,每个元素为新对象,代码更简洁:
let list = [ { 'title':'alfa', 'item':'box', 'count':2 }, { 'title':'beta', 'item':'ball', 'count':4 } ] let ev_arr = list.map(item => ({ title: item.title, item: item.item })).reverse() console.log(ev_arr)
方案三:反向遍历数组
直接反向遍历原数组,同时每次创建新对象,无需额外反转操作:
let list = [ { 'title':'alfa', 'item':'box', 'count':2 }, { 'title':'beta', 'item':'ball', 'count':4 } ] let ev_arr = [] // 从最后一个元素开始遍历 for(let i = list.length - 1; i >= 0; i--){ let ev = {} ev.title = list[i].title ev.item = list[i].item ev_arr.push(ev) } console.log(ev_arr)
内容的提问来源于stack exchange,提问作者Ravi_Djpy
相关产品推荐
相关产品推荐

