
在 javascript 递归算法中,若将二维数组直接 push 到结果集,实际存储的是原数组的引用而非副本,导致后续修改(如回溯重置)会污染已保存的结果;正确做法是创建浅拷贝(如 map + slice)以隔离数据。
在 javascript 递归算法中,若将二维数组直接 push 到结果集,实际存储的是原数组的引用而非副本,导致后续修改(如回溯重置)会污染已保存的结果;正确做法是创建浅拷贝(如 map + slice)以隔离数据。
你遇到的问题是 JavaScript 中对象引用语义的典型表现:matrix 是一个二维数组(即数组的数组),属于引用类型。当你执行 solutions.push(matrix) 时,并没有复制数组内容,而是将指向同一内存地址的引用存入 solutions。随后在回溯阶段执行 matrix[row][col] = -1,该操作会持续修改原始 matrix 对象——包括所有之前“已保存”到 solutions 中的项,因为它们都指向同一个底层数据结构。
例如,以下代码清晰复现了该问题:
const matrix = [[1, 2], [3, 4]]; const solutions = []; solutions.push(matrix); // 存入的是引用 matrix[0][0] = -1; console.log(solutions[0]); // 输出 [[-1, 2], [3, 4]] —— 已被意外修改!
✅ 正确解法:在保存结果前创建独立副本。对于二维数组,需对每一行进行浅拷贝(因行本身也是引用):
if (!nextEmpty) {
console.log(matrix);
const copy = matrix.map(row => row.slice()); // 关键:逐行拷贝
solutions.push(copy);
}row.slice() 创建一维子数组的副本,map 则生成新数组容纳这些副本——整体构成一个结构上独立的二维数组,与原 matrix 完全解耦。
立即学习“Java免费学习笔记(深入)”;
⚠️ 注意事项:
- JSON.parse(JSON.stringify(matrix)) 可实现深拷贝,但性能差且不支持函数、undefined、Date 等值,不推荐用于纯数字矩阵;
- structuredClone(matrix)(现代浏览器支持)是更健壮的深拷贝方案,但本例中二维数字数组用 map + slice 已足够高效且兼容性好;
- 切勿使用 solutions.push([...matrix]) 或 matrix.concat(),它们仅浅拷贝外层数组,内部行仍为引用,无法解决问题。
总结:JavaScript 中所有对象(包括数组)默认按引用传递。在回溯、递归或状态快照场景中,务必显式拷贝需要持久化的数据结构。对二维数组而言,array.map(row => row.slice()) 是简洁、高效、可读性强的标准实践。


















