深拷贝与浅拷贝的定义
原始数据类型
创建新数组并复制原始数据类型的值,而没有递归复制整个对象。
是这样来确定是不是深浅拷贝原始数据类型
浅拷贝(Shallow Copy):仅复制对象或数组的 引用,对于引用类型的元素(如对象、数组),它们仍然指向原数组中相同的内存位置。对于原始类型元素,浅拷贝复制的是值。
深拷贝(Deep Copy):不仅复制对象或数组的引用,还会递归地复制其中的所有元素(包括引用类型元素的内容),这样新数组和原数组完全独立,不会共享任何引用。
为什么 slice()
对原始类型元素表现得像深拷贝
当你使用 slice()
拷贝一个包含原始类型元素的数组时,它确实复制了 值,而不是引用。由于原始类型(例如数字、字符串等)是按值传递的,因此即使它是浅拷贝,修改新数组中的元素也不会影响原始数组。
例子:
javascript复制
let arr = [1, 2, 3];
let aCopy = arr.slice(); // 浅拷贝aCopy[0] = 10; // 修改aCopyconsole.log(arr); // [1, 2, 3] - arr没有变化
console.log(aCopy); // [10, 2, 3] - aCopy发生了变化
- 原始类型(数字):数组中的元素是原始类型(数字),
slice()
创建了一个新的数组aCopy
,它复制了原始数组中 值 的副本,因此修改aCopy[0]
不会影响arr[0]
。这种行为就像是 深拷贝,因为我们修改aCopy
后,原数组没有任何变化。
为什么这不是深拷贝
深拷贝 是指完全复制整个数组以及数组中的所有元素,包括嵌套的对象或数组,甚至是引用类型元素的内容。对于 引用类型元素,slice()
并不会创建新的独立对象,它只是复制了对象的引用。
例如:
javascript复制
let arr = [{ name: 'A' }, { name: 'B' }];
let aCopy = arr.slice(); // 浅拷贝aCopy[0].name = 'C'; // 修改aCopy中的对象console.log(arr[0].name); // 'C' - arr[0]也发生了变化
console.log(aCopy[0].name); // 'C' - aCopy[0]发生了变化
在这个例子中,arr
和 aCopy
中的元素是对象,它们共享相同的 引用,因此修改其中一个数组中的对象会影响另一个数组。
结论
- 对于 原始类型元素,
slice()
看起来像 深拷贝,因为它们按 值 传递。 - 对于 引用类型元素,
slice()
是 浅拷贝,它只是复制了引用,因此两个数组中引用类型元素的变化是共享的。
所以,尽管对于原始类型元素,slice()
的行为表现得像深拷贝,但它实际是 浅拷贝,因为它 复制的是值,而不是递归复制整个对象的内容。