这次的学习深拷贝参考了子匠大大的文章:《JavaScript中对象的深拷贝》
JSON.parse()&JSON.stringify()
通过JSON的两个方法使对象重新构造成新的对象实现深拷贝,它的问题在于会丢弃对象的constructor,同时必须保证处理的对象为能够被json数据结构表示,比如Number
,String
,Boolean
,Array
,扁平对象,否则无法处理。
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) ? [] : {} // 区分是数组还是对象
arguments.callee(initalObject[key],finalOjbect[key]) //调用自身函数方法
}else{
finalObject[key] = initalObject[key]
}
}
return finalObject
}
参考文章中,提到相互引用对象死循环的情况,则有下面的优化.
function deepCopy(initalObject,finalObject){
var finalObject = finalObject || {}
for(var key in initalObject){
var tempProperty = initalObject[key]
if(tempProperty === initalObject){
continue //
当自身属性引用自己的时候,跳过执行,不拷贝,避免相互引用导致内存溢出的情况
}
if(typeof initalObject[key] === "object"){
finalObject[key] = (initalObject[key].constructor === Array) ? [] : {} //区分构造函数
arguments.callee(initalObject[key],finalObject[key]) //调用自身函数方法
}else{
finalObject[key] = initalObject[key]
}
}
return finalObject
}
ps:参考文章中的方法有误,应该是if(prop === initalObj){continue}
Object.create()
使用object.create()的问题在于避开了递归,但是数组则无法做下一步处理,如果是一些特殊的构造函数实例比如正则对象同样存在这个问题
function deepCopy(initalObject,finalObject){
var finalObject = finalObject || {}
// 处理未输入新对象的情况
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()方法构造新的对象
}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