얕은 복사와 깊은 복사

Taehye.on·2023년 3월 2일
0

코드스테이츠 44기

목록 보기
13/89
post-thumbnail

🔍 얕은 복사 (Shallow Copy)

얕은 복사 (Shallow Copy) 는 '주소값'을 복사한다는 의미이다.
객체 안에 객체가 있을 경우 한개의 객체라도 원본 객체를 참조하고 있다면
얕은 복사에 해당한다.
얕은 복사를 하는 방법에 대해 알아보자.

📌 1. Object.assign()

Object.assign은 첫번째 요소로 들어온 객체에 다음 인자로 들어온 객체를 복사해준다.

let obj = { firstName: "coding", lastName: "kim" };
let copiedObj = Object.assign({}, obj);

console.log(copiedObj) // { firstName: "coding", lastName: "kim" }
console.log(obj === copiedObj) // false

📌 2. 전개 연산자(spread syntax)

전개 연산자(spread syntax)는 배열뿐만 아니라 객체 복사에도 사용 가능하다.

let obj = { firstName: "coding", lastName: "kim" };
let copiedObj = {...obj};

console.log(copiedObj) // { firstName: "coding", lastName: "kim" }
console.log(obj === copiedObj) // false

예외로 참조 자료형 내부에 참조 자료형이 중첨된 경우
위 복사 방법을 사용해도 참조 자료형 내부에 참조 자료형이 중첩된 구조는 복사할 수 없다.

🔍 깊은 복사(Deep Copy)

깊은 복사는 깊은 복사된 객체안에 객체가 있을 경우에도 원복과 참조가 완전히 끊어진 객체를 말한다.
한마디로 얕은 복사처럼 주소를 복사해 공유하는 것이 아니라,
새로운 객체안 속성만 복사해 사용 가능하다.
깊은 복사를 하는 다양한 방법을 알아보자.

📌 JSON.stringify()

JSON.stringify()는 객체를 json문자열로 변환하는데 이 때 원본 객체와의 참조가 모두 끊어진다.
객체를 json문자열로 변환 후 JSON.parse()를 이용해 다시 자바스크립트 객체로 만들어주면
깊은 복사가 된다.

const arr = [1, 2, [3, 4]];
const copiedArr = JSON.parse(JSON.stringify(arr));

console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false

📌 외부 라이브러리 사용

완전한 깊은 복사를 해야하는 경우 node.js환경에서
외부 라이브러리인 lodash 또는 ramba를 설치하면 된다.

const lodash = require('lodash');

const arr = [1, 2, [3, 4]];
const copiedArr = lodash.cloneDeep(arr);

console.log(arr); // [1, 2, [3, 4]]
console.log(copiedArr); // [1, 2, [3, 4]]
console.log(arr === copiedArr) // false
console.log(arr[2] === copiedArr[2]) // false

👨‍🏫 요약

얕은 복사 : 바로 아랫단계의 값만 복사
깊은 복사 : 내부에 존재하는 모든 값 복사.

  • 배열의 경우 slice() 메서드 또는 spread syntax 등의 방법으로 복사할 수 있다.

  • 객체의 경우 Object.assign() 또는 spread syntax 등의 방법으로 복사할 수 있다.

  • 위 방법으로 참조 자료형을 복사할 경우, 중첩된 구조 중 한 단계까지만 복사된다. (얕은 복사)

  • JavaScript 내부적으로는 중첩된 구조 전체를 복사하는 깊은 복사를 구현할 수 없다. 단, 다른 문법을 응용하여 같은 결과물을 만들 수 있다.

  • 대표적인 JSON.stringify()와 JSON.parse()를 사용하는 방법이 있지만, 예외의 케이스가 존재한다. (참조 자료형 내부에 함수가 있는 경우)

  • 완전한 깊은 복사를 반드시 해야 하는 경우, node.js 환경에서 외부 라이브러리인 lodash, 또는 ramda를 사용하면 된다.

  • 0개의 댓글