【问题标题】:JavaScript deep copy an array containing nested objects, arrays & functions?JavaScript 深拷贝包含嵌套对象、数组和函数的数组?
【发布时间】:2018-11-13 03:10:06
【问题描述】:

我有一个这样结构的数组,我正在尝试获取它的副本(修改并用于 React setState())。在 Python 中,我可以使用 copy.deepcopy(),但在 JavaScript 中找不到简单的方法。

notes=[
        {
          contents: "Hello World 1",
          function: console.log,
          children: [
            {
              contents: "Hello World A",
              function: console.log,
              children: []
            },
          ]
        },
        {
          contents: "Hello World 2",
          function: console.log,
          children: []
        }
      ]

我在 stackoverflow 上找到了这篇文章和类似的解决方案,但它们都不适合我。 https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d 两种解决方案都只是浅拷贝,JSON.parse 对函数不起作用。

我想要一个可以深度复制包含任意嵌套 JavaScript 数据类型结构的数组或对象的函数。

我宁愿不重新发明轮子,编写一个复杂的递归函数来遍历和克隆所有内容,有没有现成的解决方案?

【问题讨论】:

    标签: javascript arrays json copy deep-copy


    【解决方案1】:

    编辑- 你可以使用下面的解决方案,或者只导入 Lodash 并使用这个https://lodash.com/docs/#cloneDeep


    我正在用我找到的解决方案来回答我自己的问题。有人在我链接的文章的评论部分发布了这个,它似乎有效

    notes=[
            {
              contents: "Hello World 1",
              function: console.log,
              children: [
                {
                  contents: "Hello World A",
                  function: console.log,
                  children: []
                },
              ]
            },
            {
              contents: "Hello World 2",
              function: console.log,
              children: []
            }
          ]
    
    function deepCopy(src) {
      let target = Array.isArray(src) ? [] : {};
      for (let key in src) {
        let v = src[key];
        if (v) {
          if (typeof v === "object") {
            target[key] = deepCopy(v);
          } else {
            target[key] = v;
          }
        } else {
          target[key] = v;
        }
      }
    
      return target;
    }
    

    【讨论】:

    • 在下面查看我的答案... 一条线解决方案... const copy = notes.map(a => ({ ...a }));
    • @hev1 你是什么意思它不克隆函数?它对我有用screencast.com/t/WWaBe9Rloe
    【解决方案2】:

    如果找不到更好的答案,最短的方法

    var note2 = JSON.parse(JSON.stringify(notes))
    

    但它没有复制函数

    所以检查

    function iterationCopy(src) {
      let target = {};
      for (let prop in src) {
        if (src.hasOwnProperty(prop)) {
          target[prop] = src[prop];
        }
      }
      return target;
    }
    const source = {a:1, b:2, c:3};
    const target = iterationCopy(source);
    console.log(target); // {a:1, b:2, c:3}
    // Check if clones it and not changing it
    source.a = 'a';
    console.log(source.a); // 'a'
    console.log(target.a); // 1
    

    function bestCopyEver(src) {
      return Object.assign({}, src);
    }
    const source = {a:1, b:2, c:3};
    const target = bestCopyEver(source);
    console.log(target); // {a:1, b:2, c:3}
    // Check if clones it and not changing it
    source.a = 'a';
    console.log(source.a); // 'a'
    console.log(target.a); // 1
    

    来自Deep copy using iteration

    【讨论】:

      【解决方案3】:

      你应该使用for循环迭代它并判断项目类型,当它是对象类型时,使用递归。函数如下:

      function copy(obj1, obj2) {
        var obj2=obj2||{}; 
        for(var name in obj1) {
          if(typeof obj1[name] === "object") { 
            obj2[name]= (obj1[name].constructor===Array)?[]:{}; 
            copy(obj1[name],obj2[name]);
           } else {
            obj2[name]=obj1[name]; 
         }
       }
        return obj2; 
      }
      

      【讨论】:

        猜你喜欢
        • 2011-04-26
        • 2011-12-26
        • 1970-01-01
        • 2021-05-27
        • 2015-11-28
        • 1970-01-01
        • 2012-01-29
        • 1970-01-01
        • 2013-01-26
        相关资源
        最近更新 更多