深浅拷贝的概念:
由于引用类型在栈中只是存储了数据存储的地址,当直接把一个对象赋值给另一个对象时,其实只是把地址复制而已,当其中一个的值改变,另一个也对应改变。这样不是我们想要的结果,故而有了深浅拷贝;
浅复制:只复制一层(即当对象中属性值也为对象时不会进行深层次的复制,只复制一层)。
深复制:会递归复制(即当对象中属性值也为对象时会进行深层次复制,无论多少层)。
js的数据类型:
基本数据类型类型(即直接存储在栈内存中):Undefined、Null、Boolean、Number、String
引用类型(即存储在堆内存中):Object
浅拷贝:
数组的浅拷贝(在js中数组也是一种对象):
1、通过js自带的方法来实现
var x = [0,1,2,[3,4,[5,6]]];
var shadow1 = x.slice(0);
var shadow2 = x.concat();
console.log(shadow1 === x); //false 表示内存中存储位置不同(以下相同)
console.log(shadow2 === x); //false
console.log(shadow1[3][2] === x[3][2]); //true 表示内存中存储位置相同(以下相同)
console.log(shadow2[3][2] === x[3][2]); //true
从上面代码可以看出它只实现了一层拷贝,故为浅拷贝
2、自己通过循环来实现浅拷贝
function shadowCopy(arr) {
if(typeof arr !== 'object'){
console.log('your arg is not object');
return;
}else{
var arr0 = [];
for (var i = 0; i < obj.length; i++) {
arr0[i] = arr[i];
}
}
return arr0;
}
var shadow = shadowCopy(x);
console.log(shadow === x); //false
console.log(shadow[3][2] === x[3][2]); //true
对象的浅拷贝
var x = {
a: 1,
b: 2,
c: {
d: 3,
e: {
f: 4
}
}
}
function shadowCopy(obj) {
if(typeof obj !== 'object'){
console.log('your arg is not object');
return;
}else{
var obj0 = {};
for (var i in obj) {
obj0[i] = obj[i];
}
}
return obj0;
}
var shadow = shadowCopy(x);
console.log(shadow === x); //false
console.log(shadow.c === x.c); //true
深拷贝
1、通过JSON对象来实现(数组和标准对象都适用)
var x = [0,1,2,[3,4,[5,6]]];
var y = {
a: 1,
b: 2,
c: {
d: 3,
e: {
f: 4
}
}
}
var shadow1 = deepCopyJSON(x);
var shadow2 = deepCopyJSON(y);
console.log(shadow1 === x); //false
console.log(shadow1[3][2] === x[3][2]); /false
console.log(shadow2 === y); //false
console.log(shadow2.c.e === y.c.e); //false
function deepCopyJSON(obj) {
if(typeof obj !== 'object'){
console.log('your arg is not object');
}else{
return JSON.parse(JSON.stringify(obj));
}
}
2、通过第三方库来实现(详情参阅http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/)
3、自己实现(此方法数组和标准对象都适用)
var x = [0,1,2,[3,4,[5,6]]];
var y = {
a: 1,
b: 2,
c: {
d: 3,
e: {
f: 4
}
}
}
var shadow1 = deepCopyMyself(x);
var shadow2 = deepCopyMyself(y);
console.log(shadow1 === x); //false
console.log(shadow1[3][2] === x[3][2]); //false
console.log(shadow2 === y); //false
console.log(shadow2.c.e === y.c.e); //false
function deepCopyMyself(obj) {
if(typeof obj !== 'object'){
console.log('your arg is not object');
return;
}else{
var obj0 = obj.constructor === Array ? [] : {};
if(obj0.constructor === Object){
for (var i in obj) {
obj0[i] = typeof obj[i] === 'object' ? deepCopyMyself(obj[i]) : obj[i];
}
}else{
for (var i = 0; i < obj.length; i++) {
obj0[i] = typeof obj[i] === 'object' ? deepCopyMyself(obj[i]) : obj[i];
}
}
}
return obj0;
}