复制分浅复制和深复制两种 一般是用于描述数组或对象有嵌套结构的数据的复制
注意复制得到的数据应该是要与原数据是没有关系的,即一方数据改变了,另一方的数据不会随之改变
浅复制是指只复制了最外层的数据
深复制是指把整个数据都复制了
基础类型的数据可以直接赋值复制,因为它们没有引用,复制得到的数据和原数据没有任何关系
那如果复制一个二维数组呢?此时如果用浅复制的方式的话,那么得到的复制的数据并不是完全和原数据脱离关系
为什么说是没有完全脱离呢?因为如果数组的子元素不是基础数据类型时(如数组,对象),复制所得的元素复制的不是它的值,而是它的引用地址。所以此时原数据的这个子元素和复制所得元素是指向同一片数据的,当其任意一方里的子元素有改动时,另一方的子元素也会随之被改变。
如下面的例子:
arr = [1, [2, 3, 4], 5];
var arr1 = [];
for (var prop in arr) {
arr1[prop] = arr[prop];
}
arr1[1][2] = 1000;
console.log("arr[1][2]=" + arr[1][2]);
console.log("arr1===arr?" + (arr1 === arr));
console.log("arr1[1]===arr[1?" + (arr1[1] === arr[1]));
console.log(arr1, arr);
复制所得数据的子元素arr[1]和原数据的子元素arr[1]是指向同一片数据的,当复制所得子元素arr[1]的子元素arr1[1][2]的值改为1000时,arr[1][2]的值也为1000了。
通过打印的结果可以知道arr与arr1并不是同一个东西,但是通过浅复制方法得到的数据arr中的嵌套子元素arr[1]和arr[1]是同一个东西
既然问题在于子元素是嵌套结构时元素无法直接复制到它的值,那么我们就用递归来一层一层的复制
递归解决的思想是:
当这个数据的子元素都是基本数据类型时,直接用for in复制这个对象数据类型的数据
否则就是有嵌套结构,此时把嵌套的部分再拿出来复制,直至最里面的一层为止
递归实现深递归:
var obj1 = {
a: 1,
d: 1,
b: {
a: 2,
d: 2,
b: {
a: 3,
d: 3,
b: {
a: 4,
d: 4,
b: {
a: 5
},
c: 4
},
C: {
a: 5,
d: 5,
b: {
a: 6
},
c: 6
}
},
c: 2
},
c: 1
};
var arr1 = [
1,
2,
3,
[
5,
6,
7,
{
a: 5,
d: 5,
b: {
a: 6
},
c: 6
},
10
],
11
];
// 调用初始函数 并将返回值赋给变量
var obj = init(obj1);
var arr = init(arr1);
// 定义初始函数 函数参数为obj1 用于接收需要复制的数据 返回复制好的数据
function init(obj1) {
// 判断这个数据是数组还是对象,分别定义不同类型的复制类型 obj2为复制好的数据
if (obj1.constructor === Array) {
var obj2 = [];
} else {
var obj2 = {};
}
// 调用复制函数 参数为需要处理的数据 复制好的数据 没有返回值
copy(obj1, obj2);
return obj2;
}
// 定义复制函数
function copy(obj3, obj4) {
// 将需要处理的数据通过for in循环 判断当前所需处理数据的子元素是否有嵌套,如果没有直接复制 有的话需要
// 把当前的属性赋给当前正在复制的元素,然后判断属性值是什么类型的数据,并赋给它对应的空对象(空数组或
// 空对象) 然后递归复制函数
for (var prop in obj3) {
if (
obj3[prop].constructor !== Array &&
obj3[prop].constructor !== Object
) {
obj4[prop] = obj3[prop];
} else {
if (obj3[prop].constructor === Array) {
obj4[prop] = [];
} else {
obj4[prop] = {};
}
copy(obj3[prop], obj4[prop]);
}
}
}
console.log("obj === obj1?"+(obj === obj1));
console.log("arr === arr1?"+(arr === arr1));
console.log("obj.b === obj1.b?"+(obj.b === obj1.b));
console.log(obj1,obj);
console.log(arr1,arr);
执行结果: