如何在该场景下保留JavaScript原始二维数组?
问题原因与解决方法
为什么原始数组会被修改?
slice()是浅拷贝,它只会复制外层数组的结构,但对于数组里的子数组(引用类型),只会复制它们的引用地址,而不是创建新的子数组。所以kopija和original里的子数组其实是同一个对象,修改kopija[i][1]本质上是在修改原数组对应的子数组元素。reverse()只是反转数组的元素顺序,不会改变拷贝的深浅性质。
而一维数组能正常工作,是因为一维数组的元素是基本类型(数字、字符串等),浅拷贝会直接复制这些值的副本,修改副本不会影响原数组。
解决方法
方法1:使用map+扩展运算符实现深拷贝(推荐,灵活可控)
通过map遍历原数组的每个子数组,用扩展运算符[...]复制子数组的所有元素,生成新的子数组,再反转顺序:
let original = [["one", 1], ["two", 2], ["three", 3], ["four", 4], ["five", 5]]; let kopija = original.map(item => [...item]).reverse(); for (let i=0; i<5; i++){ while(kopija[i][1] > 1){ kopija[i][1]-- } } console.log("kopija:", kopija) console.log("original:", original)
方法2:JSON序列化反序列化(简单但有局限性)
如果数组里没有函数、Symbol、undefined等特殊类型,可以用JSON的方法实现深拷贝:
let original = [["one", 1], ["two", 2], ["three", 3], ["four", 4], ["five", 5]]; let kopija = JSON.parse(JSON.stringify(original)).reverse(); // 后续修改代码不变
注意:这种方法无法处理包含函数、Symbol、循环引用的数组。
方法3:手动循环拷贝
手动遍历原数组,逐个复制子数组的元素,同时完成反转:
let original = [["one", 1], ["two", 2], ["three", 3], ["four", 4], ["five", 5]]; let kopija = []; // 从后往前遍历原数组,实现reverse的效果 for (let i = original.length - 1; i >= 0; i--) { kopija.push([original[i][0], original[i][1]]); } // 后续修改代码不变
内容的提问来源于stack exchange,提问作者Marko P
相关产品推荐
相关产品推荐

