JavaScript嵌套过滤器问题:过滤时原始数据被修改需保留
问题描述
我想在JavaScript中实现一个嵌套过滤器,但过滤数组时原始数据会被修改,我需要保留原始数据以便后续移除过滤器。
我的代码如下:
let result = companies; result.map((item, i) => { let rows = [...result[i].table.table_rows].filter((item3) => { return Object.keys(item3).some(i => item3[i][key] === value[key]); }); result[i].table.table_rows = [...rows]; return result[i]; }); arrayFilter(result);
数据结构:
{ "companies": [ { "company": { "name": "company 1" }, "table": { "table_rows": [ { "cells": { "product_name": "prod1", "pa_size": "12" } }, { "cells": { "product_name": "prod2", "pa_size": "15" } } ] } }, { "company": { "name": "company 2" }, "table": { "table_rows": [ { "cells": { "product_name": "prod2-1", "pa_size": "12" } }, { "cells": { "product_name": "prod2-2", "pa_size": "18" } } ] } } ] }
我试过多种方法都没解决问题。
解决方案
你的问题核心是直接操作了原始数据的引用,导致原始数据被修改。要保留原始数据,必须在过滤时创建数据的副本,而非直接修改原对象。
问题分析
let result = companies;是引用赋值,result和companies指向同一块内存,操作result本质就是修改原始的companies。- 即便用
[...result[i].table.table_rows]复制了行数组,但result[i].table还是原始对象的引用,修改table_rows属性依然会改动原始数据。
修复后的代码
方法1:用结构化克隆创建深拷贝
// 先深克隆原始数据,彻底隔离原数据 const result = structuredClone(companies); result.map(item => { const filteredRows = item.table.table_rows.filter(row => { return Object.keys(row).some(keyInRow => row[keyInRow][key] === value[key]); }); // 因为已经克隆过item,修改table_rows不会影响原数据 item.table.table_rows = filteredRows; return item; }); arrayFilter(result);
方法2:手动逐层创建副本(兼容旧环境)
如果你的环境不支持structuredClone,可以手动逐层复制对象:
const result = companies.map(company => { return { // 复制company的第一层属性 ...company, // 复制table对象并替换过滤后的table_rows table: { ...company.table, table_rows: company.table.table_rows.filter(row => { return Object.keys(row).some(keyInRow => row[keyInRow][key] === value[key]); }) } }; }); arrayFilter(result);
关键要点
- 永远不要直接操作原始数据的引用,处理前必须创建副本。
- 嵌套对象需要深拷贝(
structuredClone或手动逐层复制),浅拷贝(如...扩展运算符)只能处理第一层。 map本身会返回新数组,但如果内部修改原对象属性,依然会污染原始数据,所以要确保每个层级都是新对象。
内容的提问来源于stack exchange,提问作者Alireza Bagheri
相关产品推荐
相关产品推荐

