过滤复制数组后修改新数组却影响原数组,属JS基础还是React?
问题解答
这是JavaScript基础问题,和React无关。
原因分析
JavaScript中的对象属于引用类型,filter方法返回的新数组里的元素,本质还是原数组对应对象的引用。你用[...passports]或者slice()做的是浅拷贝——仅复制了数组的结构,但数组内部的对象并没有被复制,新数组和原数组指向的是同一个对象内存地址。所以修改passportsCollection里的对象时,原数组personalDocs里的对应对象也会同步变化。
修复方案
要避免修改原数组,需要在过滤时就对每个符合条件的对象做对象层级的拷贝,推荐结合filter和map,用对象展开语法实现:
const personalDocs = [{ "IDcard": false, "passport": true, "documentnumber": "1", "dateofissue": "" }, { "IDcard": true, "passport": false, "documentnumber": "2", "dateofissue": "" }]; // 过滤同时拷贝对象,完全脱离原对象引用 const passportsCollection = personalDocs .filter(doc => doc.passport === true) .map(doc => { // 剔除IDcard属性,同时添加taken属性 const { IDcard, ...rest } = doc; return { ...rest, taken: "YES" }; }); console.log("ALL PERSONAL DOCS:") console.log(personalDocs) // 原数组不受影响 console.log("JUST PASSPORTS") console.log(passportsCollection)
如果对象嵌套结构更复杂,也可以用structuredClone实现深拷贝:
const passports = personalDocs.filter(doc => doc.passport === true); const passportsCollection = passports.map(doc => structuredClone(doc)); passportsCollection.forEach(object => { delete object['IDcard']; object.taken = "YES"; });
内容的提问来源于stack exchange,提问作者afterparty
相关产品推荐
相关产品推荐

