oris9
[Javascript] 두가지 복사.. 얕은 복사와 깊은 복사 본문
자바스크립트에는 얕은 복사(Shallow Copy)와 깊은 복사(Deep Copy)라는 개념이 있다.
또 7가지 원시타입과 참조타입이 존재한다.
깊은 복사(Deep Copy)
자바스크립트에서 값을 할당하는 방식으로 값을 복사하려고할때,
원시타입은 할당 당시 캡쳐된 값을 그대로 할당해준다. 즉 우리가 원하는대로 복사가 가능하다.
이를 `깊은 복사(Deep Copy)`라고 한다
얕은 복사(Shallow Copy)
그런데 참조타입의 경우 모두 일종의 객체라고 볼 수 있는데,
이들은 값을 가지고 있는게 아니라 값을 담고있는 메모리 주소를 가지고 있다.
그렇기 때문에 위와 같은 방법으로 복사를 하려고하면, 메모리주소가 복사되게된다.
그렇게되면 한 메모리주소에 연결된 변수가 여러개 생기는 것이고
그 중 한 변수에서 내부 값에 변화를 주면,
같은 주소를 참조하고 있는 나머지 변수들에게도 모두 변화가 생기게 된다.
이같은 경우를 `얕은 복사(Shallow Copy)`라고 말한다.
따라서 참조타입을 깊게 복사하고 싶을 때는 새로운 값을 만들어내는
`스프레드문법`이나 `Object.assign()` , `slice()`를 통해 깊게 복사가 가능하다
const arr = [1, 2, 3, 4]
const shallowCopyArr = arr
const deepCopyArr = [...arr]
arr.pop() // 가장 마지막 요소 제거
console.log(arr) // [1, 2, 3]
console.log(shallowCopyArr) // [1, 2, 3]
console.log(deepCopyArr) // [1, 2, 3, 4]
하지만 위의 방법은 참조타입의 depth가 1일때만 가능하고, 2depth일경우는 얕은 복사를 하게된다.
(내부의 참조값이 있을경우 참조값을 그대로 가져오기 때문에)
여러 depth가 존재할때, 깊은 복사하기
1. JSON.parse, JSON.stringify
JSON.stringify()는 객체를 json 문자열로 변환하는데 이 과정에서 원본 객체와의 참조가 모두 끊어지기 때문에 깊은 복사가 가능하다.
객체를 json 문자열로 변환 후, JSON.parse()를 이용해 다시 원래 객체로 만들어 준다.
const object = { a: "a", number: { one: 1, two: 2 }, arr: [1, 2, [3, 4]] };
const copy = JSON.parse(JSON.stringify(object));
가장 간단하고 쉽지만 다른 방법에 비해 느리고,
객체가 function일 경우, undefined로 처리된다.
2. 재귀 함수를 구현한 복사
복잡하다는 단점이 있다.
const object = { a: "a", number: { one: 1, two: 2 }, arr: [1, 2, [3, 4]] };
function deepCopy(object) {
if (object === null || typeof object !== "object") {
return object;
}
// 객체인지 배열인지 판단
const copy = Array.isArray(object) ? [] : {};
for (let key of Object.keys(object)) {
copy[key] = deepCopy(object[key]);
}
return copy;
}
3. Lodash 라이브러리 사용
개발시에는 라이브러리를 사용해서 깊은 복사를 안전하게 할 수 있다.
(코딩테스트 사용불가)
참고
'JavaScript' 카테고리의 다른 글
[Javascript] 코딩컨벤션 지키면서 코드 짜기 (에어비앤비 코딩 컨벤션) (0) | 2024.04.10 |
---|---|
[Javascript] 자바스크립트 이벤트(버블링? 캡쳐링? 위임?) (0) | 2024.04.06 |
[Javascript] var, let, const 열심히 비교해보기 (0) | 2024.03.30 |
[Javascript] ECMA스크립트(ECMAScript, 또는 ES) (0) | 2024.03.25 |
[Javascript] 제너레이터 함수에 대해 알아보자 (0) | 2024.03.13 |