
얕은 복사, 깊은 복사는 참조 자료형에서 발생한다.
참조 자료형부터 간단하게 짚고 넘어가보자.
메모리 공간에 값이 아닌 주소를 할당하여, 할당된 주소 안의 값을 호출 및 수정한다.
참조 자료형의 값을 다른 변수에 할당하면 주소 자체가 할당되어, 새로운 변수에서 값을 변경하면 원본 값도 함께 변경된다.
할당된 주소의 위치는 heap이라는 공간에 존재한다.
종류 : array, object, function
1. slice()
2. spread syntax(스프레드 문법)
let arr = [0, 1, 2, 3];
console.log(...arr);
// 0, 1, 2, 3 => 배열의 형태가 아닌 내부 요소들을 각각 출력
let copiedArr = [...arr];
// spread 문법으로 내부 요소들을 [] 안에 넣음으로써
// 원본의 값을 가진 새로운 배열 생성
copiedArr.push(4);
console.log(arr) // [0, 1, 2, 3]
console.log(copiedArr) // [0, 1, 2, 3, 4]
1. Object.assign()
2. spread syntax(스프레드 문법)
중첩된 구조들 중 한 단계까지만 복사를 하는 것을 얕은 복사라고 한다.
- 참조 자료형 안에 참조 자료형 요소가 있을때, 내부 참조 자료형의 주소값은 변경이 되지 않는다.
- 외부적으로는 새로운 주소를 할당하였으나, 그 안의 요소값들의 주소가 원본에서 변경되지 않는다.
let arr = [
{
name: "kimcoding",
age: 26,
job: "student"
},
{
name: "parkhacker",
age: 29,
job: "web designer"
},
];
let newArr = arr.slice();
console.log(arr === newArr) // false
console.log(arr[0] === newArr[0]) // true
내부 요소들을 모두 새롭게 복사하는 행위를 깊은 복사라고 한다.
- JS는 내부적으로 깊은 복사를 하는 기능이 없다.
- JSON.parse와 JSON.stringify를 통해 참조 자료형 ⇒ 문자열 ⇒ 참조 자료형 의 구조로 완전히 새로운 참조 자료형을 만드는 방법을 이용한다.
ramda, lodash는 deep copy를 쉽고 간편하게 사용할 수 있게 지원해준다.(관련 블로깅은 차후에 작성)
const lodash = require("lodash");
const ramda = require("ramda");
const arr = [1, 2, [3, 4]];
const lodashArr = lodash.cloneDeep(arr);
const ramdaArr = ramda.clone(arr);
console.log(lodashArr); // [1, 2, [3, 4]]
console.log(arr[2] === lodashArr[2]); // false
console.log(ramdaArr); // [1, 2, [3, 4]]
console.log(arr[2] === ramdaArr[2]); // false