含records数组的对象赋值失败,简化修改record值方案故障求解
嘿,我来帮你拆解这个问题!首先,咱们先假设你的发票对象大概是这样的(方便举例):
const invoice = { id: 1, date: '2024-05-20', customer: 'John Doe', records: [ { id: 101, item: 'Laptop', quantity: 1, price: 999 }, { id: 102, item: 'Mouse', quantity: 2, price: 25 } ] };
你说前两种方法可行,那大概率是类似「找到索引直接修改」或者「用map生成新数组替换」这类常规操作。而你尝试的简洁方法失败,大概率是忽略了这几个常见坑:
1. 直接用find修改但没做存在性检查
很多人会尝试这种看似简洁的写法:
// 看似简洁,但可能报错 invoice.records.find(r => r.id === 102).price = 30;
如果find没找到匹配的record,它会返回undefined,这时候给undefined的price赋值就会抛出Cannot set properties of undefined的错误。解决办法就是加个存在性判断,其实也没复杂多少:
const target = invoice.records.find(r => r.id === 102); if (target) target.price = 30;
2. 不可变更新时写错了链式逻辑
如果你想做不可变更新(不修改原对象,生成新对象),可能会尝试一行写法但搞砸了数组的处理。比如错误写法:
// 错误:这里的records会被赋值为30,不是更新后的数组 const updatedInvoice = {...invoice, records: invoice.records.find(r => r.id === 102).price = 30};
正确的简洁不可变写法应该是用map来更新目标元素,其他元素保持原样:
const updatedInvoice = { ...invoice, records: invoice.records.map(r => r.id === 102 ? {...r, price: 30} : r) };
3. 原对象被冻结了
如果你的invoice对象是通过Object.freeze()冻结的,那直接修改属性会静默失败(严格模式下会报错)。这时候你需要先创建一个新的解冻后的对象,再进行修改。
你可以对照一下自己的简洁写法,看看是不是踩了上面某一个坑。如果还是有问题,可以把你尝试的简洁代码贴出来,咱们再细揪~
内容的提问来源于stack exchange,提问作者M.Dimitrov
相关产品推荐
相关产品推荐

