JavaScript deep copy an array containing nested objects, arrays & functions?












0














I have an array structured like this and I'm trying to get a copy of it (to modify and use for React setState()). In Python I can use copy.deepcopy() but I can't find an easy way to do this in 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:
}
]


I found this article and similar solutions on stackoverflow, but none of them work for me.
https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d
Two solutions are only a shallow copy, and JSON.parse doesn't work on functions.



I'd like to have a function that can deep copy any array or object containing any arbitrary structure of nested JavaScript datatypes.



I'd rather not reinvent the wheel writing a complex recursive function to traverse and clone everything, is there any existing solution?










share|improve this question





























    0














    I have an array structured like this and I'm trying to get a copy of it (to modify and use for React setState()). In Python I can use copy.deepcopy() but I can't find an easy way to do this in 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:
    }
    ]


    I found this article and similar solutions on stackoverflow, but none of them work for me.
    https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d
    Two solutions are only a shallow copy, and JSON.parse doesn't work on functions.



    I'd like to have a function that can deep copy any array or object containing any arbitrary structure of nested JavaScript datatypes.



    I'd rather not reinvent the wheel writing a complex recursive function to traverse and clone everything, is there any existing solution?










    share|improve this question



























      0












      0








      0







      I have an array structured like this and I'm trying to get a copy of it (to modify and use for React setState()). In Python I can use copy.deepcopy() but I can't find an easy way to do this in 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:
      }
      ]


      I found this article and similar solutions on stackoverflow, but none of them work for me.
      https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d
      Two solutions are only a shallow copy, and JSON.parse doesn't work on functions.



      I'd like to have a function that can deep copy any array or object containing any arbitrary structure of nested JavaScript datatypes.



      I'd rather not reinvent the wheel writing a complex recursive function to traverse and clone everything, is there any existing solution?










      share|improve this question















      I have an array structured like this and I'm trying to get a copy of it (to modify and use for React setState()). In Python I can use copy.deepcopy() but I can't find an easy way to do this in 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:
      }
      ]


      I found this article and similar solutions on stackoverflow, but none of them work for me.
      https://medium.com/@Farzad_YZ/3-ways-to-clone-objects-in-javascript-f752d148054d
      Two solutions are only a shallow copy, and JSON.parse doesn't work on functions.



      I'd like to have a function that can deep copy any array or object containing any arbitrary structure of nested JavaScript datatypes.



      I'd rather not reinvent the wheel writing a complex recursive function to traverse and clone everything, is there any existing solution?







      javascript arrays json copy deep-copy






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 13 '18 at 3:29

























      asked Nov 13 '18 at 3:10









      Esostack

      3841315




      3841315
























          3 Answers
          3






          active

          oldest

          votes


















          1














          I'm answering my own question with the solution I found. Someone posted this in the comment section of the article I linked and it seems to work



          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;
          }





          share|improve this answer























          • This doesn't clone functions...
            – hev1
            Nov 13 '18 at 3:38










          • See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
            – SakoBu
            Nov 13 '18 at 3:42










          • @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
            – Esostack
            Nov 13 '18 at 3:52



















          0














          shortest way if you can not find better answer



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


          but it didnt copy functions



          so check



          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


          and



          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


          from Deep copy using iteration






          share|improve this answer





























            0














            you should use for loop iterate it and judge item type, when it is object type, use recursion. the function like:



            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;
            }





            share|improve this answer





















              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53273218%2fjavascript-deep-copy-an-array-containing-nested-objects-arrays-functions%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              3 Answers
              3






              active

              oldest

              votes








              3 Answers
              3






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              1














              I'm answering my own question with the solution I found. Someone posted this in the comment section of the article I linked and it seems to work



              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;
              }





              share|improve this answer























              • This doesn't clone functions...
                – hev1
                Nov 13 '18 at 3:38










              • See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
                – SakoBu
                Nov 13 '18 at 3:42










              • @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
                – Esostack
                Nov 13 '18 at 3:52
















              1














              I'm answering my own question with the solution I found. Someone posted this in the comment section of the article I linked and it seems to work



              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;
              }





              share|improve this answer























              • This doesn't clone functions...
                – hev1
                Nov 13 '18 at 3:38










              • See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
                – SakoBu
                Nov 13 '18 at 3:42










              • @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
                – Esostack
                Nov 13 '18 at 3:52














              1












              1








              1






              I'm answering my own question with the solution I found. Someone posted this in the comment section of the article I linked and it seems to work



              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;
              }





              share|improve this answer














              I'm answering my own question with the solution I found. Someone posted this in the comment section of the article I linked and it seems to work



              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;
              }






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited Nov 13 '18 at 3:48

























              answered Nov 13 '18 at 3:28









              Esostack

              3841315




              3841315












              • This doesn't clone functions...
                – hev1
                Nov 13 '18 at 3:38










              • See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
                – SakoBu
                Nov 13 '18 at 3:42










              • @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
                – Esostack
                Nov 13 '18 at 3:52


















              • This doesn't clone functions...
                – hev1
                Nov 13 '18 at 3:38










              • See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
                – SakoBu
                Nov 13 '18 at 3:42










              • @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
                – Esostack
                Nov 13 '18 at 3:52
















              This doesn't clone functions...
              – hev1
              Nov 13 '18 at 3:38




              This doesn't clone functions...
              – hev1
              Nov 13 '18 at 3:38












              See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
              – SakoBu
              Nov 13 '18 at 3:42




              See my answer below... One line solution... const copy = notes.map(a => ({ ...a }));
              – SakoBu
              Nov 13 '18 at 3:42












              @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
              – Esostack
              Nov 13 '18 at 3:52




              @hev1 What do you mean it doesn't clone functions? It works for me screencast.com/t/WWaBe9Rloe
              – Esostack
              Nov 13 '18 at 3:52













              0














              shortest way if you can not find better answer



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


              but it didnt copy functions



              so check



              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


              and



              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


              from Deep copy using iteration






              share|improve this answer


























                0














                shortest way if you can not find better answer



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


                but it didnt copy functions



                so check



                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


                and



                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


                from Deep copy using iteration






                share|improve this answer
























                  0












                  0








                  0






                  shortest way if you can not find better answer



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


                  but it didnt copy functions



                  so check



                  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


                  and



                  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


                  from Deep copy using iteration






                  share|improve this answer












                  shortest way if you can not find better answer



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


                  but it didnt copy functions



                  so check



                  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


                  and



                  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


                  from Deep copy using iteration







                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 13 '18 at 3:30









                  hossein sedighian

                  4816




                  4816























                      0














                      you should use for loop iterate it and judge item type, when it is object type, use recursion. the function like:



                      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;
                      }





                      share|improve this answer


























                        0














                        you should use for loop iterate it and judge item type, when it is object type, use recursion. the function like:



                        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;
                        }





                        share|improve this answer
























                          0












                          0








                          0






                          you should use for loop iterate it and judge item type, when it is object type, use recursion. the function like:



                          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;
                          }





                          share|improve this answer












                          you should use for loop iterate it and judge item type, when it is object type, use recursion. the function like:



                          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;
                          }






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 13 '18 at 3:36









                          echoLC

                          1




                          1






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.





                              Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


                              Please pay close attention to the following guidance:


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53273218%2fjavascript-deep-copy-an-array-containing-nested-objects-arrays-functions%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Xamarin.iOS Cant Deploy on Iphone

                              Glorious Revolution

                              Dulmage-Mendelsohn matrix decomposition in Python