這次的學(xué)習(xí)深拷貝參考了子匠大大的文章:《JavaScript中對(duì)象的深拷貝》
JSON.parse()&JSON.stringify()
通過JSON的兩個(gè)方法使對(duì)象重新構(gòu)造成新的對(duì)象實(shí)現(xiàn)深拷貝,它的問題在于會(huì)丟棄對(duì)象的constructor,同時(shí)必須保證處理的對(duì)象為能夠被json數(shù)據(jù)結(jié)構(gòu)表示,比如Number
,String
,Boolean
,Array
,扁平對(duì)象,否則無(wú)法處理沮稚。
function deepCopy(initalObject){
var finalObject = {}
try {
finalObject = JSON.parse(JSON.stringify(initalObject))
}
return finalObject
}
遞歸的方法
function deepCopy(initalObject,finalObject){
var finalObject = finalObject || {}
for(var key in initalObject){
if(typeof initalObject[key] === "object"){
finalObject[key] = (initalObj[key].constructor === Array) ? [] : {} // 區(qū)分是數(shù)組還是對(duì)象
arguments.callee(initalObject[key],finalOjbect[key]) //調(diào)用自身函數(shù)方法
}else{
finalObject[key] = initalObject[key]
}
}
return finalObject
}
參考文章中,提到相互引用對(duì)象死循環(huán)的情況,則有下面的優(yōu)化.
function deepCopy(initalObject,finalObject){
var finalObject = finalObject || {}
for(var key in initalObject){
var tempProperty = initalObject[key]
if(tempProperty === initalObject){
continue //
當(dāng)自身屬性引用自己的時(shí)候,跳過執(zhí)行,不拷貝,避免相互引用導(dǎo)致內(nèi)存溢出的情況
}
if(typeof initalObject[key] === "object"){
finalObject[key] = (initalObject[key].constructor === Array) ? [] : {} //區(qū)分構(gòu)造函數(shù)
arguments.callee(initalObject[key],finalObject[key]) //調(diào)用自身函數(shù)方法
}else{
finalObject[key] = initalObject[key]
}
}
return finalObject
}
ps:參考文章中的方法有誤,應(yīng)該是if(prop === initalObj){continue}
Object.create()
使用object.create()的問題在于避開了遞歸,但是數(shù)組則無(wú)法做下一步處理,如果是一些特殊的構(gòu)造函數(shù)實(shí)例比如正則對(duì)象同樣存在這個(gè)問題
function deepCopy(initalObject,finalObject){
var finalObject = finalObject || {}
// 處理未輸入新對(duì)象的情況
for(var key in initalObject){
if(initalObject[key] === initalObject){
continue
}
if(typeof initalObject[key] === "object"){
finalObject[key] = (initalObject[key].constructor === Array) ? [] : Object.create(initalObject[key]) //通過Object.create()方法構(gòu)造新的對(duì)象
}else{
finalObject[key] = initalObject[key]
}
}
return finalObject
}
參考文章:
http://www.dengzhr.com/js/1180
https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/arguments/callee