仅当ID存在于数组中时为字典添加指定键的异常排查
问题描述
我尝试根据数组中存在的值(同时也是字典键值对中的值)更新字典,但发现当值匹配并为字典添加额外键后,后续所有值也会被更新。尝试在后续出现时删除该键,却会把所有实例中的该键都删掉。
示例代码
const dd = { somedata : 'hello', anotherset: 'bye', data : { udo: { id: 123456789 } } } const someId = [987, 654, 123, 567] const arr = [123, 456] const someFunc = (arr) => { for(const id of someId){ dd.data.udo.customer_id = id; //c for(const a of arr){ if(a === dd.data.udo.customer_id){ dd.data.udo.test = 'test_account'; } else { if('test_account' === dd.data.udo.test){ delete dd.data.udo.test; } console.log(JSON.stringify(dd)); continue } } } } console.log(JSON.stringify(someFunc(arr)));
实际输出
{"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":987}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":987}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":654}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":654}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":123}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":567}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":567}}}
期望输出
{"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":987}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":987}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":654}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":654}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":123,"test":"test_account"}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":567}}} {"somedata":"hello","anotherset":"bye","data":{"udo":{"id":123456789,"customer_id":567}}}
解决方案
问题核心是你一直在修改同一个dd.data.udo对象的引用,所有循环操作的都是同一个对象,导致之前的修改会覆盖或影响后续逻辑。正确的做法是每次遍历someId时,创建一个新的udo对象副本,保证每个循环的对象独立。
修改后的代码如下:
const dd = { somedata : 'hello', anotherset: 'bye', data : { udo: { id: 123456789 } } } const someId = [987, 654, 123, 567] const arr = [123, 456] const someFunc = (arr) => { for(const id of someId){ // 每次循环创建新的udo对象副本,基于原对象扩展 const currentUdo = { ...dd.data.udo, customer_id: id }; // 检查当前id是否在arr中,决定是否添加test字段 if(arr.includes(id)){ currentUdo.test = 'test_account'; } // 生成当前的完整对象 const currentDd = { ...dd, data: { ...dd.data, udo: currentUdo } }; // 遍历arr输出两次(对应原逻辑的两次循环) for(const a of arr){ console.log(JSON.stringify(currentDd)); } } } someFunc(arr);
说明
- 使用对象扩展运算符
{...}创建原对象的副本,避免修改原引用。 - 先判断当前
id是否在arr中,直接给新对象添加或不添加test字段,不需要后续删除操作。 - 每个循环生成独立的对象,输出时不会互相干扰,完全符合期望结果。
内容的提问来源于stack exchange,提问作者Emil11
相关产品推荐
相关产品推荐

