zoukankan      html  css  js  c++  java
  • JavaScript中深拷贝实现

    JavaScript 中深拷贝实现
     
    拷贝时候涉及到:
    1、循环结构
    2、判断数组 Array 还是对象 Object
     
    函数实现
    /**
     * 获取满足条件的数组中的第一个元素
     * @param {Array} list 将要筛选的数组
     * @param {Function} f 用来过滤的函数
     */
    function find(list, f) {
      return list.filter(f)[0]
    }
    /**
     * 深拷贝对象,同时考虑到了循环引用的情况
     * 缓存了所有的嵌套对象和它的拷贝
     * 如果检测到循环引用,返回拷贝,防止了无限循环
     * @param {Object} obj 需要拷贝的对象
     * @param {Array} cache 用来判断是否循环引用,存储对象以及对象的拷贝
     */
    function deepCopy(obj, cache = []) {
      // 为空或者不是对象则返回原 obj
      if (obj === null || typeof obj !== 'object') {
        return obj
      }
    
      // 若是循环结构,则返回之前对象的 copy,而不是引用
      const hit = find(cache, c => c.original === obj)
      if (hit) {
        return hit.copy
      }
    
      const copy = Array.isArray(obj) ? [] : {}
      // 将 copy 放入 cache 中
      // 我们可能在递归中引用 copy
      cache.push({
        original: obj,
        copy
      })
    
      Object.keys(obj).forEach(key => {
        copy[key] = deepCopy(obj[key], cache)
      })
    
      return copy
    }

    应用

    1、非嵌套例子:
    const original = {
      a: 1,
      b: 'string',
      c: true,
      d: null,
      e: undefined
    }
    const copy = deepCopy(original)
    console.log('copy === original :', copy === original) 
    // copy === original : false
    console.log('copy :', JSON.stringify(copy, null, 2)) 
    // copy : {
    //     "a": 1,
    //     "b": "string",
    //     "c": true,
    //     "d": null
    // }

    2、嵌套例子: 

    const original = {
      a: {
        b: 1,
        c: [
          2,
          3,
          {
            d: 4
          }
        ]
      }
    }
    const copy = deepCopy(original)
    console.log('copy === original :', copy === original)
    // copy === original : false
    console.log('copy :', JSON.stringify(copy, null, 2))
    // copy : {
    //     "a": {
    //         "b": 1,
    //         "c": [
    //         2,
    //         3,
    //         {
    //             "d": 4
    //         }
    //         ]
    //     }
    // }
     
    3、循环引用
    const original = {
      a: 1
    }
    original.circularExample = original
    
    const copy = deepCopy(original)
    console.log('copy === original :', copy === original)
    // copy === original : false
    console.log('copy :', copy)
    // 这里循环引用不可使用 JSON.stringify 来转换,会报错
    // copy : { a: 1, circularExample: [Circular] }
    都读到最后了、留下个建议如何
  • 相关阅读:
    实际成本法
    加权平均法,移动加权平均法,先进先出法(计算策略)
    xss缺陷--脚本语言嵌入漏洞
    关于耳机插入,设备管理中:声音设置中却显示"没有耳机插入"
    国家十二类稀缺人才
    apache2.4搭建php5.53问题总结
    任意多个有序结合求交集
    类似于大数相加的一个题
    数字的最大组合
    计算二叉树每层的和
  • 原文地址:https://www.cnblogs.com/linjunfu/p/10958618.html
Copyright © 2011-2022 走看看