JS深浅拷贝 总结

204 阅读1分钟

浅拷贝实现

只拷贝对象的第一层, 对于键值是引用数据类型,新旧对象对应的键值任然指向同一个地址。

  1. Object.assign()
 const o1 = {
        name: 'jiefei',
        age: 20,
        info: {
          addr: 'chongqing',
        },
      }
      const newO1 = Object.assign({}, o1)
      o1.info.addr = 'fengjie'
      console.log(newO1.info.addr) // fengjie
  1. 对象扩展运算符
 const o2 = {
        name: 'jiefei',
        age: 20,
        info: {
          addr: 'chongqing',
        },
      }
      const newO2 = { ...o2 }
      o2.info.addr = 'fengjie'
      console.log(newO2.info.addr) // fengjie
  1. 自己实现
     function lightClone(obj) {
        let newObj = new Object()
        for (let key in obj) {
          if (obj.hasOwnProperty(key)) {
            newObj[key] = obj[key]
          }
        }
        return newObj
      }

      const o3 = {
        name: 'jiefei',
        age: 20,
        info: {
          addr: 'chongqing',
        },
      }
      const newO3 = lightClone(o3)
      o3.info.addr = 'fengjie'
      console.log(newO3.info.addr) // fengjie

深拷贝实现

得到的是一个全新的对象, 和旧的对象不存在关联。

  1. JSON.parse(JSON.stringify())
 const o4 = {
        name: 'jiefei',
        age: 20,
        info: {
          addr: 'chongqing',
        },
      }
      const newO4 = JSON.parse(JSON.stringify(o4))
      o4.info.addr = 'fengjie'
      console.log(newO4.info.addr) // chongqing
  • 弊端 如果键值是 函数、正则、日期类型的拷贝会失败
 const o5 = {
        fn: function () {},
        date: new Date(),
        reg: /^$[1-9]/,
      }

      const newO5 = JSON.parse(JSON.stringify(o5))
      console.log(newO5)
      newO5:  {
        date: '2021-02-18T08:13:31.947Z'
        reg: {
        }
      }
  1. 自己实现
function deepClone(obj) {
        if (obj === null) return null
        // 克隆函数
        // if (typeof obj === 'function') return new Function('return' + obj.toString())()
        if (typeof obj === 'function') return obj.bind(null)
        if (typeof obj !== 'object') return obj
        if (obj instanceof RegExp) return new RegExp(obj)
        if (obj instanceof Date) return new Date(obj)
		
        // 根据对象的constructor 创建对应的对象类型
        const newObj = new obj.constructor()
        for (let key in obj) {
          if (obj.hasOwnProperty(key)) {
            newObj[key] = deepClone(obj[key])
          }
        }
        return newObj
 }