淺復(fù)制:淺復(fù)制是復(fù)制引用,復(fù)制后的引用都是指向同一個(gè)對(duì)象的實(shí)例,彼此之間的操作會(huì)互相影響
深復(fù)制:深復(fù)制不是簡(jiǎn)單的復(fù)制引用,而是在堆中重新分配內(nèi)存,并且把源對(duì)象實(shí)例的所有屬性都進(jìn)行新建復(fù)制,以保證深復(fù)制的對(duì)象的引用圖不包含任何原有對(duì)象或?qū)ο髨D上的任何對(duì)象,復(fù)制后的對(duì)象與原來(lái)的對(duì)象是完全隔離的
數(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
深拷貝
1.數(shù)組slice方法
對(duì)于array對(duì)象的slice函數(shù),
返回一個(gè)數(shù)組的一段。(仍為數(shù)組)
arrayObj.slice(start, [end])
參數(shù)
arrayObj
必選項(xiàng)。一個(gè) Array 對(duì)象。
start
必選項(xiàng)。arrayObj 中所指定的部分的開始元素是從零開始計(jì)算的下標(biāo)。
end
可選項(xiàng)。arrayObj 中所指定的部分的結(jié)束元素是從零開始計(jì)算的下標(biāo)。
說(shuō)明
slice 方法返回一個(gè) Array 對(duì)象,其中包含了 arrayObj 的指定部分。
slice 方法一直復(fù)制到 end 所指定的元素,但是不包括該元素。如果 start 為負(fù),將它作為 length + start處理,此處 length 為數(shù)組的長(zhǎng)度。如果 end 為負(fù),就將它作為 length + end 處理,此處 length 為數(shù)組的長(zhǎng)度。如果省略 end ,那么 slice 方法將一直復(fù)制到 arrayObj 的結(jié)尾。如果 end 出現(xiàn)在 start 之前,不復(fù)制任何元素到新數(shù)組中。
eg:
var arr = ["One","Two","Three"];
var arrtoo = arr.slice(0);
arrtoo[1] = "set Map";
document.writeln("數(shù)組的原始值:" + arr + "<br />");//Export:數(shù)組的原始值:One,Two,Three
document.writeln("數(shù)組的新值:" + arrtoo + "<br />");//Export:數(shù)組的新值:One,set Map,Three
2.數(shù)組的concat方法
concat() 方法用于連接兩個(gè)或多個(gè)數(shù)組。
該方法不會(huì)改變現(xiàn)有的數(shù)組,而僅僅會(huì)返回被連接數(shù)組的一個(gè)副本。
語(yǔ)法
arrayObject.concat(arrayX,arrayX,......,arrayX)
說(shuō)明
返回一個(gè)新的數(shù)組。該數(shù)組是通過(guò)把所有 arrayX 參數(shù)添加到 arrayObject 中生成的。如果要進(jìn)行 concat() 操作的參數(shù)是數(shù)組,那么添加的是數(shù)組中的元素,而不是數(shù)組。
對(duì)象的深拷貝
JSON對(duì)象是ES5中引入的新的類型(支持的瀏覽器為IE8+),JSON對(duì)象parse方法可以將JSON字符串反序列化成JS對(duì)象,stringify方法可以將JS對(duì)象序列化成JSON字符串,借助這兩個(gè)方法,也可以實(shí)現(xiàn)對(duì)象的深復(fù)制。
var source = {
name:"source",
child:{
name:"child"
}
}
var target = JSON.parse(JSON.stringify(source));
//改變target的name屬性
target.name = "target";
console.log(source.name); //source
console.log(target.name); //target
//改變target的child
target.child.name = "target child";
console.log(source.child.name); //child
console.log(target.child.name); //target child
從代碼的輸出可以看出,復(fù)制后的target與source是完全隔離的,二者不會(huì)相互影響。
這個(gè)方法使用較為簡(jiǎn)單,可以滿足基本的深復(fù)制需求,而且能夠處理JSON格式能表示的所有數(shù)據(jù)類型,但是對(duì)于正則表達(dá)式類型、函數(shù)類型等無(wú)法進(jìn)行深復(fù)制(而且會(huì)直接丟失相應(yīng)的值),同時(shí)如果對(duì)象中存在循環(huán)引用的情況也無(wú)法正確處理