淺拷貝與深拷貝
首先深拷貝和淺拷貝只針對像 Object, Array 這樣的復(fù)雜對象的。簡單來說,淺拷貝只拷貝一層對象的屬性,而深拷貝則遞歸拷貝了所有層級。
淺拷貝
在使用JavaScript對數(shù)組進(jìn)行操作的時候,我們經(jīng)常需要將數(shù)組進(jìn)行備份,事實(shí)證明如果只是簡單的將它賦予其他變量,那么我們只要更改其中的任何一個,然后其他的也會跟著改變。
var arr = ["One","Two","Three"];
var arrto = arr;
arrto[1] = "test";
document.writeln("數(shù)組的原始值:" + arr + "<br />");
//Export:數(shù)組的原始值:One,test,Three
document.writeln("數(shù)組的新值:" + arrto + "<br />");
//Export:數(shù)組的新值:One,test,Three
像上面的這種直接賦值的方式就是淺拷貝,很多時候,這樣并不是我們想要得到的結(jié)果。因?yàn)闇\拷貝只會將對象的各個屬性進(jìn)行依次拷貝,并不會進(jìn)行遞歸拷貝,而 JavaScript 存儲對象都是存地址的,所以淺拷貝會導(dǎo)致 arr 和 arrto 指向同一塊內(nèi)存地址。
深拷貝
而深拷貝則不同,它不僅將原對象的各個屬性逐個拷貝出去,而且將原對象各個屬性所包含的對象也依次采用深拷貝的方法遞歸拷貝到新對象上。即深拷貝會產(chǎn)生新的地址,修改一個對象的屬性,不會改變另一個對象的屬性。
深拷貝的實(shí)現(xiàn)方法
數(shù)組
1. js的slice函數(shù)
arrayObj.slice(start, [end]);
如var newarr = arr.slice(0);
2.js的concat方法
arrayObject.concat(arrayX,arrayX,......,arrayX);
如var newarr = arr.slice(0);
對象
1.通過JSON解析解決
JSON.stringify:將對象轉(zhuǎn)化為字符串;
JSON.parse :將字符串轉(zhuǎn)化為對象;
如var newobj= JSON.parse(JSON.stringify(obj));
2.遍歷對象屬性
var deepCopy= function(source) {
var result={};
for (var key in source) {
result[key] = typeof source[key]===’object’? deepCoyp(source[key]): source[key];
}
return result;
}
復(fù)合寫法
var cloneObj = function(obj){
var str, newobj = obj.constructor === Array ? [] : {};
if(typeof obj !== 'object'){
return;
} else if(window.JSON){
str = JSON.stringify(obj), //系列化對象
newobj = JSON.parse(str); //還原
} else {
for(var i in obj){
newobj[i] = typeof obj[i] === 'object' ?
cloneObj(obj[i]) : obj[i];
}
}
return newobj;
};