數(shù)據(jù)保存到對象以后會涉及到拷貝的問題,而數(shù)據(jù)保存的格式多樣,這就涉及到了深拷貝和淺拷貝的問題固阁。
產(chǎn)生的原因:
var arr1 = [1,2,3,4,5];
var arr2 = arr1;
arr2[1] = 6;
document.write("arr1: " + arr1 + "<br/>"); //打印結(jié)果:arr1: 1,6,3,4,5
document.write("arr2: " + arr2);//打印結(jié)果:arr2: 1,6,3,4,5
//打印結(jié)果:
//arr1: 1,6,3,4,5
//\arr2: 1,6,3,4,5
用以上方式將數(shù)組拷貝到arr2中是直接讓兩個對象同時指向同一片內(nèi)存區(qū)域夭禽,更改其中的一個,另一個也會更改,為了使兩個對象保存以后不會互相影響传于,用下面的一個簡單地例子說明:
var arr1 = [1,2,3,4,5];
var arr2 = [];
for(var i = 0; i < arr1.length; i++){
arr2[i] = arr1[i];
}
arr2[1] = 6;
document.write("arr1: " + arr1 + "<br/>");
document.write("arr2: " + arr2);
//打印結(jié)果:
//arr1: 1,2,3,4,5
//arr2: 1,6,3,4,5
使用循環(huán)將arr1里面的數(shù)據(jù)一一添加到新的對象中囱挑,這樣打印出來的結(jié)果就不會相互影響,也就是一個淺拷貝沼溜。
Array的slice函數(shù)也可以實現(xiàn)淺拷貝:
//此方法只針對Array
var arr1 = [1,2,3,4,5];
var arr2 = arr1.slice(1);
arr2[0] = "a";
document.write(arr1 + "<br/>");
document.write(arr2);
//輸出結(jié)果:
//1,2,3,4,5
//a,3,4,5
但是這個方法也只是淺拷貝的一種平挑,數(shù)組有多層的時候也是不行的,例如:
var arr1 = [[1,11],[2,22],[3,33]];
var arr2 = arr1.slice(1);
arr2[0][1] = "a";
document.write(arr1 + "<br/>");
document.write(arr2);
//輸出結(jié)果:
//1,11,2,a,3,33
//2,a,3,33
Array的concat函數(shù)也是淺拷貝系草,實例如下:
var arr1 = [1,2,3];
var arr2 = [4,5,6];
var arr3 = arr1.concat(arr2);
arr2[1] = "aa";
document.write(arr3);
//輸出結(jié)果:
//1,2,3,4,5,6
生成的第三個數(shù)組是獨立的通熄,受arr1和arr2影響。但也只能實現(xiàn)淺拷貝找都。
淺拷貝只是拷貝了對象最外面的一層唇辨,但是并不是所有的對象都是簡單到只有一層,所以出現(xiàn)了深拷貝能耻,利用遞歸將對象深拷貝助泽。
用遞歸寫了一個例子:
var object1 = [1,2,3,4,{a:"aaa", b:"bbb"},6,7,[8,9,{c:"ccc", d:"ddd"}]];
function deepCopy(obj, newObj) {
var newObj = newObj || ((obj.constructor === Array) ? [] : {});
for (var i in obj) {
if (typeof obj[i] === 'object') {
newObj[i] = (obj[i].constructor === Array) ? [] : {};
deepCopy(obj[i], newObj[i]);
} else {
newObj[i] = obj[i];
}
}
return newObj;
}
var arr = deepCopy(object1);
arr[4].a = "ccc";
console.log(object1);// [1,2,3,4,{a:"aaa", b:"bbb"},6,7,[8,9,{c:"ccc", d:"ddd"}]]
console.log(arr);// [1,2,3,4,{a:"ccc", b:"bbb"},6,7,[8,9,{c:"ccc", d:"ddd"}]]
在拷貝的時候檢查數(shù)據(jù)的格式,然后分情況拷貝嚎京。這樣的方法可以提高代碼的重用嗡贺,在數(shù)據(jù)格式未知的情況下,避免出錯鞍帝,但是這樣寫在某些情況下也會降低代碼執(zhí)行的效率诫睬,比如數(shù)據(jù)已知并且單一的情況下,淺拷貝就可以滿足帕涌,并且可以提高代碼執(zhí)行的效率摄凡。