本文不会具体介绍扩展运算符的基本用法。
只是分享在项目中踩坑的点。
你以为的扩展运算符只是复制的功能,其实会偷偷修改你的原数组
案例:
假如arr = [...arr2]
,修改arr
的值会改变arr2
的值吗?
解决方案:
case1
使用 arr = [...arr2]
语法创建一个新的数组 arr
,并将 arr2
中的元素复制到 arr
中。这意味着 arr
和 arr2
是不同的数组实例,它们的引用不同。因此,修改 arr
不会直接影响到 arr2
。
例如:
int[] arr2 = {1, 2, 3};
int[] arr = [...arr2];
arr[0] = 10;
System.out.println(Arrays.toString(arr)); // 输出:[10, 2, 3]
System.out.println(Arrays.toString(arr2)); // 输出:[1, 2, 3]
在上述示例中,将 arr2
的值复制到 arr
中后,修改 arr
的第一个元素并不会影响到 arr2
。
case2
但需要注意的是,如果数组 arr2
中的元素是对象的引用,而不是基本类型(如整数),那么 arr
和 arr2
中的元素引用将指向相同的对象。在这种情况下,修改对象本身可能会影响到两个数组。
例如:
class Person {
String name;
public Person(String name) {
this.name = name;
}
}
Person[] arr2 = {new Person("Alice"), new Person("Bob")};
Person[] arr = [...arr2];
arr[0].name = "Charlie";
System.out.println(arr[0].name); // 输出:Charlie
System.out.println(arr2[0].name); // 输出:Charlie
在这个示例中,修改 arr
中的第一个元素的名称属性同时也会影响到 arr2
中的第一个元素,因为它们引用的是同一个 Person
对象。
总结起来,对于基本类型数组,使用 arr = [...arr2]
创建的新数组与原始数组是独立的。但对于引用类型数组,修改对象本身可能会影响到两个数组。
如果我想要创建一个与arr2相同的数组,并且修改它不会影响到arr2,应该怎么做?
要创建一个与 arr2
相同的数组,并确保修改它不会影响到 arr2
,你可以使用数组的拷贝方法来实现。以下是一些常见的方法:
可以使用 slice()
方法或扩展运算符 ([...arr2]
) 创建一个新的数组副本。
const arr2 = [1, 2, 3];
const arr = arr2.slice(); // 或者 const arr = [...arr2];
arr[0] = 10;
console.log(arr); // 输出:[10, 2, 3]
console.log(arr2); // 输出:[1, 2, 3]
请注意,这些方法是针对普通的数组(如整数数组)的,如果你使用的是引用类型数组,如对象数组,需要确保对象也被复制,而不仅仅是引用。在这种情况下,你可能需要使用深拷贝方法,以确保对象的属性也被复制。
综上所述,通过使用适当的数组拷贝方法,你可以创建一个与 arr2
相同的数组,并确保对它的修改不会影响到 arr2
。
拷贝一个对象数组,并且新数组改变后不要影响旧数组
如果你想要拷贝一个对象数组,并确保新数组的修改不会影响到旧数组,你需要进行深拷贝(deep copy)。深拷贝会创建一个新的数组,并逐个复制对象及其属性,而不仅仅是复制对象的引用。具体方法如下:
- JavaScript:你可以使用
JSON.parse(JSON.stringify(arr2))
进行深拷贝。
const arr2 = [{ name: 'Alice' }, { name: 'Bob' }];
const arr = JSON.parse(JSON.stringify(arr2));
arr[0].name = 'Charlie';
console.log(arr); // 输出:[{ name: 'Charlie' }, { name: 'Bob' }]
console.log(arr2); // 输出:[{ name: 'Alice' }, { name: 'Bob' }]
- 你可以通过遍历原数组并逐个复制对象来创建一个新的数组。
注意,深拷贝方法适用于对象数组,其中对象包含属性。如果对象中还包含其他嵌套对象或集合等,你需要相应地对嵌套对象进行深拷贝。
const arr2 = [{ name: 'Alice' }, { name: 'Bob' }];
// 方法2: 使用递归进行深拷贝
function deepCopy(obj) {
if (typeof obj !== 'object' || obj === null) {
return obj;
}
let copy = Array.isArray(obj) ? [] : {};
for (let key in obj) {
if (obj.hasOwnProperty(key)) {
copy[key] = deepCopy(obj[key]);
}
}
return copy;
}
const arr = deepCopy(arr2);
arr[0].name = 'Charlie';
console.log(arr); // 输出:[{ name: 'Charlie' }, { name: 'Bob' }]
console.log(arr2); // 输出:[{ name: 'Alice' }, { name: 'Bob' }]
在上述示例中,我们使用了两种方法来实现深拷贝。第一种方法使用 JSON.stringify
将对象数组转换为字符串,然后使用 JSON.parse
将字符串转换回对象数组,从而实现深拷贝。第二种方法是使用递归函数 deepCopy
对对象进行逐个属性的深拷贝。
不论你选择哪种方法,都可以创建一个与 arr2
相同的对象数组,并确保对新数组的修改不会影响到旧数组 arr2
。