клонирование нового объекта из существующего в JavaScript - PullRequest
0 голосов
/ 16 ноября 2018

У меня есть многоэтапный объект javascript, подобный этому:

const source = {
  prev: [],
  current: {
    list: [{ a: 1, b: 2, c: 3 }],
    data: [{ c: 1, b: 2 }]
  },
  id: 12,
  next: []
};

и я хотел бы создать его свежую копию. Я знаю, что если я использую что-то вроде let copy = { ...source };, это похоже на мелкую копию. Поэтому, если я изменю эти массивы или объекты в source, они также изменятся в copy.

Есть ли в любом случае, что путем деструктуризации я получаю свежую копию всех предметов? или я должен сделать это вручную для каждого уровня глубоко, как это:

copy.prev = [...source.prev]
copy.current.list = [...source.current.list]
copy.current.data= [...source.current.data]

и т. Д.

Ответы [ 4 ]

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

С простым объектом, содержащим объекты, массивы и примитивы, не так уж много кода для простого рекурсивного клонирования всего.

Просто верните примитивы, map() массивы и уменьшите ключи объекта, передаваязначения обратно. Что-то вроде:

const source = {prev: [],current: {list: [{ a: 1, b: 2, c: 3 }],data: [{ c: 1, b: 2 }]},id: 12,next: []};

function clone(obj){
    return (typeof obj == 'object')
        ? (Array.isArray(obj))
            ? obj.map(i => clone(i)) 
            : Object.entries(obj).reduce((o, [key, value]) => 
              Object.assign(o, {[key]: clone(value)}), {})  
        : obj

}

let a_clone = clone(source)
console.log(JSON.stringify(a_clone, null, 2))


// is the clone deep? should be false
console.log(a_clone.prev === source.prev)
console.log(a_clone.current.list === source.current.list)
0 голосов
/ 16 ноября 2018

Вы можете использовать JSON.stringify

    const source = {
  prev: [],
  current: {
    list: [{ a: 1, b: 2, c: 3 }],
    data: [{ c: 1, b: 2 }]
  },
  id: 12,
  next: []
};

newObj = JSON.parse(JSON.stringify(source));
0 голосов
/ 16 ноября 2018

Вы можете деконструировать так:

const source = {
  prev: [],
  current: {
    list: [{ a: 1, b: 2, c: 3 }],
    data: [{ c: 1, b: 2 }]
  },
  id: 12,
  next: []
};

const {
current: {list: listClone, data: dataClone}
} = source

console.log(listClone, dataClone)
0 голосов
/ 16 ноября 2018

Есть старый способ сделать это, но все еще работает:

var cloned = JSON.parse(JSON.stringify(original));
...