实现对象的深拷贝和浅拷贝

183 阅读2分钟

浅拷贝和深拷贝都是对于JS中的引用类型而言的,浅拷贝就只是复制对象的引用(堆和栈的关系,简单类型Undefined,Null,Boolean,Number和String是存入堆,直接引用,object array 则是存入桟中,只用一个指针来引用值),如果拷贝后的对象发生变化,原对象也会发生变化。只有深拷贝才是真正地对对象的拷贝。

深拷贝

实现深拷贝1
function deepClone(source) {
// 判断复制的目标是数组还是对象
  const targetSource = Array.isArray(source) ? [] : {}
  if(typeof source !=='object') return
  // 遍历目标
  for(let key in obj){
    if(source.hasOwnProperty(key)){
     // 如果值是对象,就递归一下 
      if(source[keys] && typeof source[keys] === 'object'){
        targetSource[keys] =  Array.isArray(source[keys]) ? [] : {}
        targetSource[keys] = deepClone(source[keys])
      }else{ // 如果不是,就直接赋值
        targetSource[keys] = source[keys]
      }
    }
  }
}
实现深拷贝2
const closeArray = JSON.parse(JSON.stringify(source))

// 注意只能拷贝一些简单的情况:属性的值是简单类型,简单的对象类型,数组 // 如果是undefined,function, sybmbol 会在转换过程中被忽略

浅拷贝:对象是多层次的情况,改变目标对象会改变源对象

浅拷贝1
首层浅拷贝
function shallowClone(source){
  let targetSource = Array.isArray(source) ? [] : {}
  for(let key in source){
    if(source.hasOwnProperty(key)){
      targetSource[key] = source[key]
    }
  }
  return targetSource
}
浅拷贝1
const cloneArray = source.slice()
浅拷贝2
const cloneArray = source.slice()
浅拷贝3
const cloneArray = Object.assign({}, source)
  • source函数是一个取值的函数,Object.assign不会复制这个取值函数,只会拿到这个值之后,将这个值复制过去
const source = {
  get foo() { return a}
}
const target = {}
Object.assign(target,source)
//targrt = {foo: "a"}
浅拷贝4
cosnt cloneArray = {...source}

总结

赋值运算符 = 实现的是浅拷贝,只拷贝对象的引用值; JavaScript 中数组和对象自带的拷贝方法都是“首层浅拷贝”; JSON.stringify 实现的是深拷贝,但是对目标对象有要求(非 undefined,function); 若想真正意义上的深拷贝,请递归。