Clone 과 DeepClone에 대해서 아래 블로그에서 알아보았습니다.

Lodash에는 이를 쉽게 수행할 수 있는 함수가 있는데 clone과 cloneDeep이며 자주 사용하는 Lodash 함수 중 하나입니다.

_.clone 함수는 얕은 복사(shallow copy)를 수행하며, 객체나 배열의 속성 값이 기본 타입(primitive type)일 경우 해당 값을 복사합니다. 하지만 객체나 배열의 속성 값이 참조 타입(reference type)일 경우, 참조하는 메모리 주소를 복사하므로 원본 객체나 배열과 복사본 객체나 배열이 같은 메모리를 참조하게 됩니다.

_.cloneDeep 함수는 깊은 복사(deep copy)를 수행하며, 객체나 배열의 모든 속성 값을 재귀적으로 탐색하여 복사합니다. 따라서 원본 객체나 배열과 복사본 객체나 배열은 서로 다른 메모리를 참조하게 됩니다.

예를 들어, 다음과 같은 원본 객체가 있다고 가정해보겠습니다.

const original = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY'
  },
  hobbies: ['reading', 'traveling', 'swimming']
};

이제 _.clone_.cloneDeep 함수를 사용하여 객체를 복사해보겠습니다.

const shallowCopy = _.clone(original);
const deepCopy = _.cloneDeep(original);

shallowCopy 변수는 원본 객체를 얕은 복사한 결과를 저장하고, deepCopy 변수는 원본 객체를 깊은 복사한 결과를 저장합니다.

이제 original 객체와 shallowCopy 객체, deepCopy 객체의 값을 변경해보겠습니다.

original.name = 'Mike';
original.address.street = '456 Park Ave';
original.hobbies.push('hiking');

이제 각각의 객체를 출력해보겠습니다.

console.log(original);
// { name: 'Mike',
//   age: 30,
//   address: { street: '456 Park Ave', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming', 'hiking' ] }

console.log(shallowCopy);
// { name: 'John',
//   age: 30,
//   address: { street: '456 Park Ave', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming', 'hiking' ] }

console.log(deepCopy);
// { name: 'John',
//   age: 30,
//   address: { street: '123 Main St', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming' ] }

original 객체는 이름, 주소, 취미에 대해 변경을 가했으므로 변경된 값이 출력됩니다. shallowCopy 객체는 얕은 복사를 수행했으므로, 주소와 취미에 대해서는 변경된 값이 반영되었습니다. deepCopy 객체는 깊은 복사를 수행했으므로, 원본 객체를 변경해도 복사본 객체에는 영향을 미치지 않았습니다.

따라서 객체를 복사할 때, 해당 객체의 구조와 내부 값이 어떤 형태인지에 따라서 _.clone_.cloneDeep 함수를 적절히 사용해야 합니다.

다음은 더 많은 예제를 통해 _.clone_.cloneDeep 함수의 사용법을 알아보겠습니다.

예제 1) 얕은 복사

const original = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY'
  },
  hobbies: ['reading', 'traveling', 'swimming']
};

const shallowCopy = _.clone(original);

original.name = 'Mike';
original.address.street = '456 Park Ave';
original.hobbies.push('hiking');

console.log(original);
// { name: 'Mike',
//   age: 30,
//   address: { street: '456 Park Ave', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming', 'hiking' ] }

console.log(shallowCopy);
// { name: 'John',
//   age: 30,
//   address: { street: '456 Park Ave', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming', 'hiking' ] }

예제 2) 깊은 복사

const original = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY'
  },
  hobbies: ['reading', 'traveling', 'swimming']
};

const deepCopy = _.cloneDeep(original);

original.name = 'Mike';
original.address.street = '456 Park Ave';
original.hobbies.push('hiking');

console.log(original);
// { name: 'Mike',
//   age: 30,
//   address: { street: '456 Park Ave', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming', 'hiking' ] }

console.log(deepCopy);
// { name: 'John',
//   age: 30,
//   address: { street: '123 Main St', city: 'New York', state: 'NY' },
//   hobbies: [ 'reading', 'traveling', 'swimming' ] }

예제 3) 중첩된 객체

const original = {
  name: 'John',
  age: 30,
  address: {
    street: '123 Main St',
    city: 'New York',
    state: 'NY',
    zip: {
      code: '10001'
    }
  }
};

const deepCopy = _.cloneDeep(original);

original.address.zip.code = '10002';

console.log(original);
// { name: 'John',
//   age: 30,
//   address: { street: '123 Main St', city: 'New York', state: 'NY', zip: { code: '10002' } } }

console.log(deepCopy);
// { name: 'John',
//   age: 30,
//   address: { street: '123 Main St', city: 'New York', state: 'NY', zip: { code: '10001' } } }

예제 4) 배열

const original = [1, 2, {name: 'John'}, [3, 4]];

const deepCopy = _.cloneDeep(original);

original[2].name = 'Mike';
original[3].push(5);

console.log(original);
// [ 1, 2, { name: 'Mike' }, [ 3, 4, 5 ] ]

console.log(deepCopy);
// [ 1, 2, { name: 'John' }, [ 3, 4 ] ]

위 예제에서는 원본 배열과 복사본 배열을 생성하고, 원본 배열의 값을 변경한 뒤 각각의 배열을 출력해봤습니다. 배열의 경우에는 _.clone_.cloneDeep 함수 모두 원본 배열과 복사본 배열이 서로 다른 메모리를 참조하게 됩니다.

위 예제를 통해 객체와 배열을 복사할 때, 얕은 복사와 깊은 복사의 차이를 이해하고, 해당 함수를 적절히 사용하는 방법을 알아보았습니다.