美文网首页Js面试
js深拷贝和浅拷贝怎么实现深拷贝

js深拷贝和浅拷贝怎么实现深拷贝

作者: A_dfa4 | 来源:发表于2020-12-07 11:22 被阅读0次

    js变量复制,复杂类型存的是地址值,浅拷贝只是把地址值复制了一份,拷贝对象和原对象指向同一个地址, 一个改变也会影响另外一个

    浅拷贝

    1. 对象复制
    2. Object.assign()
    const target = { a: 1 };
    const source1 = { b: 2 };
    const source2 = { c: 3 };
    Object.assign(target, source1, source2);  // 返回  {a:1, b:2, c:3}
    target // {a:1, b:2, c:3}
    
    1. ...obg 扩展运算符

    深拷贝

    1. JSON,parse(JSON.stringify)
      1. 拷贝的对象的值中如果有函数,undefined,symbol则经过JSON.stringify()序列化后的JSON字符串中这个键值对会消失
      1. 无法拷贝不可枚举的属性,无法拷贝对象的原型链
      1. 拷贝Date引用类型会变成字符串
    // let date = new Date()
    // undefined
    // DataTransfer
    // ƒ DataTransfer() { [native code] }
    // date
    // Mon Dec 07 2020 10:48:10 GMT+0800 (中国标准时间)
    // JSON.stringify(new Date())
    // ""2020-12-07T02:48:58.265Z""
    
      1. 拷贝RegExp引用类型会变成空对象
      1. 对象中含有NaN、Infinity和-Infinity,则序列化的结果会变成null
      1. 无法拷贝对象的循环应用(即obj[key] = obj)

    深拷贝实现

    var obj = {
      a: 2,
      b: [1,2,3,{aa: 11, bb:22}],
      c: function () {
        console.log("cccc")
      },
      d: undefined,
      e: 'e',
      f: /^\d+$/
    }
    
    // let obj1 = JSON.parse(JSON.stringify(obj))  // 会丢失c的function 和d的undefined 正则({})/日期格式 会改变
    // 方法1
    function deepClone (obj) {
      let objClone = Array.isArray(obj) ? [] : {};
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {  // 如果是私有属性 不是原型上的才进入
          if (Object.prototype.toString.call(obj[key]) === '[object Object]') {
            deepClone(obj[key])
          } else {
            objClone[key] = obj[key]
          } 
        }
      }
      return objClone
    } 
    let obj2 = deepClone(obj)
    console.log(obj2)
    
    // 方法2
    function deepClone2 (obj) {
      //过滤特殊情况
      if (obj === null) return;
      if (typeof obj != 'object') return  obj;
      if (obj instanceof RegExp) {
        return new RegExp(obj)
       }
      // => 不直接创建空对象的目的,克隆的结果和之前保持相同的所属类
      let newObj = new obj.constructor;
      for (let key in obj) {
        if (obj.hasOwnProperty(key)) {
          newObj[key] = deepClone2(obj[key])
        }
      }
      return newObj;
    }
    
    let obj3 = deepClone2(obj);
    console.log(obj3)
    

    相关文章

      网友评论

        本文标题:js深拷贝和浅拷贝怎么实现深拷贝

        本文链接:https://www.haomeiwen.com/subject/ypgtqhtx.html