JavaScript 原生js深拷贝的实现

这次的学习深拷贝参考了子匠大大的文章:《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

你可能感兴趣的:(JavaScript 原生js深拷贝的实现)