React Router v6.6.2教程:数据更新函数逻辑存疑但功能正常
嘿,我完全懂你的困惑——这段代码看起来好像根本没修改原contacts数组,却能成功更新联系人数据,核心原因在于JavaScript中对象是引用类型,咱们一步步拆解清楚:
1. 找到的contact是原数组对象的引用
当你执行let contact = contacts.find(contact => contact.id === id);时,这里的contact并不是一个全新的对象副本,它直接指向了contacts数组里匹配到的那个对象在内存中的位置。简单说,contact变量和数组里的目标对象是同一个东西,只是名字不同而已。
2. 修改引用对象的属性就是修改原数组里的对象
接下来的Object.assign(contact, updates);这行代码,直接把updates里的属性合并到了contact指向的对象上。因为这个对象就是原数组里的那个对象,所以此时contacts数组里的目标对象已经被悄悄更新了——你不需要“重新把contact放回数组”,因为它本来就在数组里!
3. 持久化的是已经更新后的数组
最后调用await set(contacts);时,传入的确实是原来的contacts数组变量,但数组里的目标对象已经被修改过了,所以set函数把整个数组存入localforage时,保存的自然就是更新后的版本。
举个极简的例子帮你理解这个引用逻辑:
// 模拟你的contacts数组 const contacts = [{id: 1, name: "张三"}]; // 找到匹配的对象 const target = contacts.find(c => c.id === 1); // 修改这个对象的属性 target.name = "李四"; // 查看原数组 console.log(contacts); // 输出: [{id: 1, name: "李四"}]
看到没?我们根本没碰contacts数组本身,但修改target的属性后,数组里的对象直接变了——这就是引用类型的特性。
这种写法在JavaScript里很常见,虽然看起来有点“隐形”,但完全符合语言的工作机制。你之前的困惑很正常,很多刚接触JS引用类型的开发者都会踩这个认知坑😉
内容的提问来源于stack exchange,提问作者web dev in training

