JavaScript глубоко копировать массив, содержащий вложенные объекты, массивы и функции? - PullRequest
0 голосов
/ 13 ноября 2018

У меня есть структурированный массив, и я пытаюсь получить его копию (чтобы изменить и использовать для 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.

Я бы предпочел не изобретать колесо для написания сложной рекурсивной функции для обхода и клонирования всего, есть ли существующее решение?

Ответы [ 3 ]

0 голосов
/ 13 ноября 2018

кратчайший путь, если вы не можете найти лучший ответ

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

из Глубокое копирование с использованием итерации

0 голосов
/ 13 ноября 2018

вы должны использовать для итерации цикла и оценки типа элемента, когда это тип объекта, используйте рекурсию.функция как:

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; 
}
0 голосов
/ 13 ноября 2018

Редактировать - вы можете использовать решение ниже или просто импортировать 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;
}
...