자바스크립트에서 객체(Object) 타입을 복사, 복제(Clone)하는 방법에 대하여 알아봅니다. 어떻게 하면 똑같은 객체를 하나 더 만들 수 있을지 알아봅니다.


! 객체 복사, 복제 앞서 반드시 알아둘 사항
객체를 복사하기 이 전에 중요한 개념을 이해하는 것이 좋겠죠. 바로 깊은 복사(Deep copy)얇은 복사(Shallow copy)입니다.

자바스크립트의 객체를 새로운 변수에 선언하게 되면 참조 형태로 값이 존재하게 되는데 이를 얇은 복사, Shallow copy라고 합니다. 여기서 참조를 설명하면... 새롭게 생긴 변수의 값이 변하면 기존의 객체 역시 함께 변하게 되죠. 아래와 같이 말이죠.
site = { a: 1, b: 2 };
site2 = site; // site2 변수를 선언하여 { a: 1, b: 2 } 값을 가지게 됨

// site2의 변수값을 변경하면 site의 값도 변하는 지 확인하기
site2.a = 3;

console.log(site); // 출력값은 아래처럼 프로퍼티 a가 함께 변함
{ a: 3, b: 2 };

두 변수를 비교해도 true 값을 반환합니다.
site === site2 // true 반환

그럼 아래에서 객체 복사의 여러 방법을 알아봅니다.



# 자바스크립트 객체(Object) 복제, 복사하기자바스크립트의 객체 타입을 복사하는 방법으로 아래와 같이 몇 가지 방법을 사용할 수 있는데요 ~ 하나씩 알아보도록 하겠습니다.


! ES9의 ... 기호를 사용하는 방법이 방법은 ES 9(ES 2018) 방법입니다. 즉 최신 브라우저가 아닌 경우 babel 등을 사용하는 Polyfill 등이 필요할 수 있습니다. 장점은 보시는 것처럼 매우 간단하게 사용할 수 있습니다.
obj = { a: 1, b: 2 };

cloneObj = { ...obj };

보시는 것처럼 {} 내부에 ...를 사용한 것이 전부입니다. 이제 새로운 객체 _cloneObj가 생성되었습니다. 두 타입을 비교해볼까요?
obj === cloneObj // false를 반환

두 변수를 비교하면 false를 반환합니다. 그런데 주의할 점이 있습니다. 바로 내부 프로퍼티값이 객체인 경우입니다. 다시 말해 객체 내부에 또 다른 객체를 가진 경우입니다.

@ 내부 값으로 객체가 존재하는 경우
아레처럼 obj 내부에는 또 다른 객체가 존재하는데요 바로 c 프로퍼티로 객체 타입을 가지고 있습니다. 
obj = { a: 1, b: 2, c: { aa: 3 } };

cloneObj = { ...obj };

문제는 이처럼 내부 객체가 존재하는 경우 깊은 복사(deep copy)의 예외가 존재할 수 있다는 점입니다. 즉 내부 함수는 deep copy가 아닌 참조 형태로 복사됩니다. 간단하게 타입을 비교해보면 알 수 있죠.
obj === cloneObj // false 반환
obj.c === cloneObj.c // true 반환

그럼 만약 내부 객체까지 모두 deep copy하려면 어떤 방법을 사용해야 할까요? 이 경우 아래에서 다음의 방법을 사용하면 됩니다.

1. JSON 객체 사용하기
2. lodash cloneDeep() 사용하기

이를 염두하시고 아래를 봐주시기 바랍니다.


! JSON 객체를 사용하는 방법JSON 객체를 사용하여 문자열을 가져오고 이를 다시 객체로 만드는 방법입니다. 즉 두 가지 메소드가 사용됩니다.

JSON.stringify() // 문자열로 가져오기
JSON.parse() // 문자열을 객체로 변환하기


자세한 방법은 아래와 같습니다.
obj = { a: 1, b: 2 };

cloneObj = JSON.parse(JSON.stringify(obj));

기존 객체를 문자열로 변환하고 변환 된 문자열을 다시 객체로 변환하니 완전히 새로운 객체가 생성되게 됩니다. 이 방법은 객체 내부의 객체(inner object)까지 복사되는 방법입니다. 참고로 성능을 기준으로는 우수한 방법은 아닐 수 있습니다.


! Object 객체 메소드 assign() 사용하기
호환성도 우수하고 많이 사용되는 방법입니다. Object 객체의 내부 메소드를 사용합니다.
obj = { a: 1, b: 2 };

cloneObj = Object.assign({}, obj);

동일한 값을 가지는 cloneObj가 생성됩니다.


여기까지 알아본 위의 방법들은  자바스크립트 만으로 객체를 복사할 수 있는 방법이었습니다. 아래부터는 라이브러리 등을 사용하는 방법을 알아봅니다.


! lodash clone() 메서드 사용하는 방법
lodash는 컬렉션(Collection) 데이터에 사용할 수 있는 유용한 라이브러리입니다. 객체의 복사 역시 clone()을 사용하여 만들 수 있습니다.
obj = { a: 1, b: 2 };
cloneObj = _.clone(obj);

clone()은 내부객체까지 모두 Deep copy하지 않습니다. 이런 이유로 cloneDeep() 메소드가 존재합니다.
obj = { a: 1, b: 2, c: { aa: 3 } };
cloneObj = _.cloneDeep(obj);

obj.c === cloneObj.c; // false를 반환함

cloneDeep()을 사용하여 참조형태가 아닌 Deep copy를 수행할 수 있습니다.


! jQuery 제이쿼리 사용하는 방법
만약 제이쿼리 라이브러리를 사용하는 경우 아래와 같이 extend() 메소드를 사용할 수 있으니 참고하세요.
obj = { a: 1, b: 2 };

cloneObj = $.extend({}, obj);

이번에도 복사된 새로운 객체 cloneObj가 생성되었습니다. 참고로 내부 객체는 동일하게 참조형태로 복사됩니다.

여기까지 객체를 복사, 복제하는 다양한 방법을 알아봤습니다.