[JS] 얕은복사 (Shallow Copy)와 깊은복사 (Deep Copy)

Junyeong Kim·2024년 1월 23일
0

개발

목록 보기
5/16
post-thumbnail

원시값과 참조값

JS의 데이터 타입은 기본적으로 원시값과 참조값으로 나뉜다.

  • 원시값 : Number, String, Boolean, Null, Undefined
  • 참조값 : Object, Symbol

원시값의 경우 복사해서 할당할 때 각각 다른 메모리에 할당되므로 원래의 값과 복사된 값이 서로 영향을 미치지 않지만, 참조값의 경우 기본적으로 객체가 저장된 메모리의 주소가 지정되어 있기 때문에 복사할 때에도 같은 주솟값을 가리키게 된다.

얕은 복사와 깊은 복사는 이러한 객체(참조값)를 복사하는 각각의 방법이다.

얕은 복사 (Shallow Copy)


얕은 복사를 하게 되면 주소가 저장된다.
아래와 같은 결과가 나타나게 된다.

const arr = [1, 2, 3, 4];
const copied_arr = arr;

arr.push(5);

console.log(copied_arr); // output : [1, 2, 3, 4, 5]

arr과 copied_arr이 같은 객체를 가리키는 주소를 담고 있기 때문에 위와 같은 결과가 나타난다.

얕은 복사를 하는 방법

Object.assign(새로운 객체, 복사할 객체)

const obj = {
  'kim': 1,
  'lee': {
    'park': 2,
  },
};

const copied_obj = Object.assign({}, obj);

copied_obj.lee.park = 3

console.log(obj.lee.park); // output: 3
console.log(copied_obj.lee.park); // output: 3

첫번째 인자에 넣어준 객체에 두번째 인자에 넣어준 객체가 복사된다.

const obj2 = {
  'kim': 1,
  'lee': 2,
};

const copied_obj2 = Object.assign({}, obj);

copied_obj2.lee = 3

console.log(obj2.lee); // output: 2
console.log(copied_obj2.lee); // output: 3

2차원 객체 이상부터는 얕은복사로 이루어지지만, 1차원 객체에서는 깊은 복사로 사용할 수 있다.

spread 연산

const obj = {
  'kim': 1,
  'lee': {
    'park': 2,
  },
};

const copied_obj = {...obj};

copied_obj.lee.park = 3

console.log(obj.lee.park); // output: 3
console.log(copied_obj.lee.park); // output: 3

... 뒤에 복사할 객체를 써주면 복사된다.

const obj2 = {
  'kim': 1,
  'lee': 2,
};

const copied_obj2 = {...obj2};

copied_obj2.lee = 3

console.log(obj2.lee); // output: 2
console.log(copied_obj2.lee); // output: 3

spread 연산도 마찬가지로 2차원 객체 이상부터는 얕은복사로 이루어지지만, 1차원 객체에서는 깊은 복사로 사용할 수 있다.

깊은복사 (Deep Copy)

깊은 복사를 하게 되면 값까지 복사하여 저장된다. 새로운 주소가 생겨서 원본으로의 참조가 끊기는 것이다.

깊은 복사를 하는 방법

JSON.parse(JSON.stringify(복사할 객체))

const obj = {
  'kim': 1,
  'lee': {
    'park': 2,
  },
};

const copied_obj = JSON.parse(JSON.stringify(obj));

copied_obj.lee.park = 3

console.log(obj.lee.park); // output: 2
console.log(copied_obj.lee.park); // output: 3

사용하기는 쉽지만, 시간이 오래 걸린다고 한다!

재귀함수를 통한 복사

const obj = {
  'kim': 1,
  'lee': {
    'park': 2,
  },
};

function copyObj(obj) {
  const result = {};

  for (let key in obj) {
    if (typeof obj[key] === 'object') {
      result[key] = copyObj(obj[key]);
    } else {
      result[key] = obj[key];
    }
  }

  return result;
}

const copied_obj = copyObj(obj);

copied_obj.lee.park = 3

console.log(obj.lee.park); // output: 2
console.log(copied_obj.lee.park); // output: 3

알고리즘(?)으로써 구현해야한다는 것이 좀 성가시는 것 같다... 위의 로직은 아래 블로그에 써주신 것을 가져와보았다. [JavaScript] 얕은 복사, 깊은 복사

개인적으로 참조값을 복사해서 가져다 쓰고 하는 활용이 아직 좀 헷갈리게 느껴진다. 두개의 차이를 잘 숙지하고 적절한 용도에 맞추어서 사용해보자!

정보 출처

https://velog.io/@th0566/Javascript-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC#2-jsonstringify
https://velog.io/@y_jem/%EC%9E%90%EB%B0%94%EC%8A%A4%ED%81%AC%EB%A6%BD%ED%8A%B8-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC%EC%99%80-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC#2-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%ACdeep-copy
https://velog.io/@yukyung/Spread-Operator%EB%8A%94-%EC%96%95%EC%9D%80-%EB%B3%B5%EC%82%AC%EC%9D%BC%EA%B9%8C-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC%EC%9D%BC%EA%B9%8C

profile
개발자가 되고싶어?? 네

0개의 댓글

관련 채용 정보