数组排序防原数组篡改:拷贝方案选型及异常排查
React数组拷贝排序最佳实践与异常排查
在React项目中,为避免sort()方法修改原数组graphData,目前大量使用JSON.parse(JSON.stringify())做深拷贝(版本1)。现考虑替换为[...array]浅拷贝的版本2,或支持null/undefined兜底为空数组的版本3,同时注意到slice()也能实现类似浅拷贝效果。此外项目出现sortedGraphData.filter() is not a function异常——虽已给graphData设[]兜底并提前判断,仍报错,怀疑是JSON深拷贝导致数组类型异常,以下是相关最佳实践及排查建议。
代码示例
版本1(深拷贝)
let sortedGraphData = JSON.parse(JSON.stringify(graphData)) .sort((a, b) => { return a.playerStint > b.playerStint ? 1 : -1; });
版本2(浅拷贝)
let sortedGraphData = [...graphData] .sort((a, b) => { return a.playerStint > b.playerStint ? 1 : -1; });
版本3(带兜底的浅拷贝)
let sortedGraphData = [...(graphData ?? [])] .sort((a, b) => { return a.playerStint > b.playerStint ? 1 : -1; });
异常代码片段
// 初始化、深拷贝、排序 const graphData = someOtherArray || []; const sortedGraphData = JSON.parse(JSON.stringify(graphData)) .sort((a, b) => { return a.playerStint > b.playerStint ? 1 : -1; }); // 提前判断空数组 if (!sortedGraphData || sortedGraphData.length === 0) { return; } // 过滤操作 const finalData = sortedGraphData.filter(...) // 报错:sortedGraphData.filter() is not a function(说明sortedGraphData不是数组)
最佳实践建议
优先用浅拷贝替代JSON深拷贝
- 除非数组元素是需完全隔离的复杂嵌套对象,否则不要用
JSON.parse(JSON.stringify())。这个方法存在诸多缺陷:会丢失函数、Symbol、循环引用对象,还会将undefined等特殊值转为null,性能也远低于浅拷贝。 - 推荐使用版本3:
[...(graphData ?? [])],或等价的(graphData ?? []).slice()。两者既能实现浅拷贝,又能处理graphData为null/undefined的情况,确保最终得到的是数组。 - 若
graphData元素为简单对象(无嵌套修改需求),浅拷贝完全足够——sort()仅改变数组顺序,不会修改元素本身,浅拷贝后的数组排序不会影响原数组。
- 除非数组元素是需完全隔离的复杂嵌套对象,否则不要用
兜底逻辑用
??替代||更严谨||会将空数组[]、0等假值替换为兜底值,而??仅在值为null/undefined时触发兜底,更符合业务需求。比如版本3中的graphData ?? []就比异常代码里的someOtherArray || []更安全。
异常排查建议
针对sortedGraphData.filter() is not a function问题,按以下步骤排查:
验证
JSON.parse(JSON.stringify(graphData))的返回值- 在排序前添加日志:
console.log('graphData类型:', typeof graphData, '是否为数组:', Array.isArray(graphData)),确认graphData是否为预期数组。 - 在
sortedGraphData定义后加日志:console.log('sortedGraphData:', sortedGraphData, '是否为数组:', Array.isArray(sortedGraphData)),直接查看其真实类型。
- 在排序前添加日志:
修复提前判断的逻辑漏洞
- 原判断
if (!sortedGraphData || sortedGraphData.length === 0)无法识别非数组的真值(如空对象{}),应改为先校验数组类型:if (!Array.isArray(sortedGraphData) || sortedGraphData.length === 0) { return; }。
- 原判断
排查
someOtherArray的真实值- 添加日志:
console.log('someOtherArray:', someOtherArray),确认其是否为预期数组。若someOtherArray是真值非数组(如对象、字符串),graphData = someOtherArray || []会将非数组赋值给graphData,导致后续JSON处理后仍为非数组。
- 添加日志:
内容的提问来源于stack exchange,提问作者Canovice
相关产品推荐
相关产品推荐

