JavaScript中对象数组属性递增时的引用异常问题咨询
问题:修改指定年份的月份值时,所有年份的对应值都被修改
我创建了对象month、数组year和对象list,随后将数组year的元素作为键添加到对象list中,并将对象month添加到list对应键的数组中。代码如下:
var year = [2021, 2020]; var month = {"jan": 0, "feb": 0, "mar": 0}; var list={}; for (let i = 0; i < 2; i++) { list[year[i]] = [month]; } list['2021'][0]['feb']+=1; console.log(list);
执行list['2021'][0]['feb']+=1;尝试按年份递增月份值时出现问题:
- 期望结果:
{'2021': [{'jan':0, 'feb':1, 'mar':0}], '2020': [{'jan':0, 'feb':0, 'mar':0}]} - 实际结果:
{'2021': [{'jan':0, 'feb':1, 'mar':0}], '2020': [{'jan':0, 'feb':1, 'mar':0}]}
问题原因
在JavaScript中,对象属于引用类型。你在循环中给list[year[i]]赋值的是同一个month对象的引用,而非新的对象副本。也就是说,list['2021'][0]和list['2020'][0]指向内存中的同一个对象,修改其中一个的属性,另一个自然会同步变化。
解决方法
每次循环时创建month对象的新副本,避免复用同一个引用。常见实现方式有三种:
1. 使用对象展开语法(推荐)
var year = [2021, 2020]; var month = {"jan": 0, "feb": 0, "mar": 0}; var list={}; for (let i = 0; i < 2; i++) { // 展开month对象创建新副本 list[year[i]] = [{...month}]; } list['2021'][0]['feb']+=1; console.log(list);
2. 使用Object.assign()
var year = [2021, 2020]; var month = {"jan": 0, "feb": 0, "mar": 0}; var list={}; for (let i = 0; i < 2; i++) { // 用Object.assign创建新对象副本 list[year[i]] = [Object.assign({}, month)]; } list['2021'][0]['feb']+=1; console.log(list);
3. 手动创建新对象
如果对象结构简单,也可以直接在循环里手动定义新对象:
var year = [2021, 2020]; var list={}; for (let i = 0; i < 2; i++) { list[year[i]] = [{"jan": 0, "feb": 0, "mar": 0}]; } list['2021'][0]['feb']+=1; console.log(list);
以上三种方式都能确保每个年份对应的是独立对象,修改其中一个不会影响其他年份的属性值。
内容的提问来源于stack exchange,提问作者B_J
相关产品推荐
相关产品推荐

