浅拷贝和深拷贝

139 阅读2分钟
  • 浅拷贝和深拷贝区别:假设a由b复制而来,当修改b时,如果a跟着变了,说明这是拿人手短——————浅拷贝;如果a没变,那就是自食其力——————深拷贝。实际上:深拷贝在计算机中开辟了一块新的内存地址用于存放复制的对象,而浅拷贝仅仅是指向被拷贝的内存地址,如果原地址中对象被改变了,那么浅拷贝出来的对象也会相应改变
  • 浅拷贝实现:
  1. Object.assign
      const a = {
         age: 1,
         c: { e: { z: 1 }}
      }
      a.age = 2
      const d = Object.assign(a)
      console.log(d.age)// 2
  1. es6的扩展运算符...
      const a = {
         age: 1,
         c: { e: { z: 1 }}
      }
      const b = { ...a }
      a.age = 2
      a.c.e = 1
      console.log(b.c)// {e:1}
      console.log(b.age)// 1

只要拷贝前后对象第一层的属性值不是指向同一个引用,深层属性值指向同一个引用,都叫浅拷贝,所以解构赋值就是浅拷贝

  • 深拷贝实现
  1. JSON.parse(JSON.stringify(object))
      const c = {
         age: 1,
         time: { min: 1 },
         name: undefined,
         sex: null,
         tel: /123123/,
         say: () => {
            console.log('hahha')
         }
      }
      const d = JSON.parse(JSON.stringify(c))
      c.time = 11
      console.log(d)
      // { age: 1, sex: null, tel: {} ,time:{min:1}}

注意事项:这种拷贝方法不可以拷贝一些特殊的属性(例如正则表达式,undefined,function)

  1. 递归复制所有层级属性
   function deepClone(obj) {
         // 定义一个变量 并判断是数组还是对象
         var objClone = Array.isArray(obj) ? [] : {}
         if (obj && typeof obj === 'object' && obj != null) {
            // 判断obj存在并且是对象类型的时候 因为null也是object类型,所以要单独做判断
            for (var key in obj) { //  循环对象类型的obj
               if (obj.hasOwnProperty(key)) { //  判断obj中是否存在key属性
                  if (obj[key] && typeof obj[key] === 'object') {
                     //  判断如果obj[key]存在并且obj[key]是对象类型的时候应该深拷贝
                     ,即在堆内存中开辟新的内存
                     objClone[key] = deepClone(obj[key])
                  } else { //  否则就是浅复制
                     objClone[key] = obj[key]
                  }
               }
            }
         }
         return objClone
      }

注意事项:递归运行效率低,次数过多的话容易造成栈溢出