深淺拷貝的概念:
由于引用類型在棧中只是存儲了數(shù)據(jù)存儲的地址,當(dāng)直接把一個對象賦值給另一個對象時,其實只是把地址復(fù)制而已,當(dāng)其中一個的值改變,另一個也對應(yīng)改變。這樣不是我們想要的結(jié)果,故而有了深淺拷貝;
淺復(fù)制:只復(fù)制一層(即當(dāng)對象中屬性值也為對象時不會進行深層次的復(fù)制,只復(fù)制一層)。
深復(fù)制:會遞歸復(fù)制(即當(dāng)對象中屬性值也為對象時會進行深層次復(fù)制,無論多少層)。
js的數(shù)據(jù)類型:
基本數(shù)據(jù)類型類型(即直接存儲在棧內(nèi)存中):Undefined、Null、Boolean、Number、String
引用類型(即存儲在堆內(nèi)存中):Object
淺拷貝:
數(shù)組的淺拷貝(在js中數(shù)組也是一種對象):
1、通過js自帶的方法來實現(xiàn)
var x = [0,1,2,[3,4,[5,6]]];
var shadow1 = x.slice(0);
var shadow2 = x.concat();
console.log(shadow1 === x); //false 表示內(nèi)存中存儲位置不同(以下相同)
console.log(shadow2 === x); //false
console.log(shadow1[3][2] === x[3][2]); //true 表示內(nèi)存中存儲位置相同(以下相同)
console.log(shadow2[3][2] === x[3][2]); //true
從上面代碼可以看出它只實現(xiàn)了一層拷貝,故為淺拷貝
2、自己通過循環(huán)來實現(xiàn)淺拷貝
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對象來實現(xiàn)(數(shù)組和標(biāo)準(zhǔn)對象都適用)
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、通過第三方庫來實現(xiàn)(詳情參閱http://jerryzou.com/posts/dive-into-deep-clone-in-javascript/)
3、自己實現(xiàn)(此方法數(shù)組和標(biāo)準(zhǔn)對象都適用)
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;
}