对于数组的深拷贝,浅拷贝网上的资料比较杂,自己整理一下,如有错误,请指出。
首先什么是深拷贝,浅拷贝,
大多数的说法是 深拷贝在复制数组的时候,在计算机中新开辟了一块内存,存放新复制的对象。原数组改变不影响复制的数组
浅拷贝是只是复制了原数组的引用,两个数组指向同一个地址,改变一个,另一个随着改变。
还有一种说法是如果数组中对象包含其他属性,浅复制不会全都复制,深拷贝是全都拷贝了。
即:浅拷贝是指拷贝对象时仅仅拷贝对象本身(包括对象中的基本变量),而不拷贝对象包含的引用指向的对象。深拷贝不仅拷贝对象本身,而且拷贝对象包含的引用指向的所有对象。举例来说更加清楚:对象A1中包含对B1的引用,B1中包含对C1的引用。浅拷贝A1得到A2,A2 中依然包含对B1的引用,B1中依然包含对C1的引用。深拷贝则是对浅拷贝的递归,深拷贝A1得到A2,A2中包含对B2(B1的copy)的引用,B2 中包含对C2(C1的copy)的引用。
稍微总结了一下,深拷贝和浅拷贝应包括这两种情况
即:深拷贝指的是对象A复制给对象B时,A和B指向的不是同一个对象,通时A的对象成员AA和B的对象成员BB也指的不是同一个对象,如有更深层对象,以此类推。
浅拷贝只复制指向某个对象的指针,而不复制对象本身,新旧对象还是共享同一块内存。但深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象。
javascript深拷贝方法:
1.slice
var arrA=['a','b','c'];
var arrB=arrA.slice(0);
arrB[0]='aa';
console.log(arrA);
console.log(arrB);
2.concat
var arrA=['a','b','c'];
var arrB=arrA.concat();
arrB[0]='aaa';
console.log(arrA);
console.log(arrB);
3.挨个循环
for (var i = 0; i < arrA.length; ++i) {
arrB[i] = arrA[i];
}
1.Java深复制 clone
int[] intArrB=intArrA.clone();
2.arraycopy
System.arraycopy(intArrA,0,intArrB,0,intArrA.length)
java,javascript 共通方法:利用递归,挨个复制:
以js为例:
function copy( sourceObj , c) {
var c = c || ( Array.isArray(sourceObj) ? [ ] : {} );
for (var i in sourceObj) {
if (typeof sourceObj[i] === 'object') {
c[i] = Array.isArray(sourceObj[i]) ? [] : {};
copy (sourceObj[i], c[i]);
} else {
c[i] = sourceObj[i];
}
}
return c;
}
测试了一下,java的clone和arrayCopy也只是一层深拷贝,如果对象还有对象,则需要重写clone或者用递归