희락코딩

JavaScript _tip / 얕은 복사와 깊은 복사 (Shallow copy, Deep copy) 본문

프로그래밍/자바스크립트 꿀팁 개념

JavaScript _tip / 얕은 복사와 깊은 복사 (Shallow copy, Deep copy)

Hello JoyCoding 2021. 4. 25. 19:45
728x90
반응형

얕은 복사와 깊은복사 (Shallow copy, Deep copy)

이번 블로깅은 얕은복사와 깊은 복사에 대해 개념을 정리 하였습니다. 다소 너무 생소하고 어렵게 느껴지는 부분이 많았던 내용입니다. 하지만 이개념을 알아야 나중에 데이터를 다룰때 유용하게 쓰일 수 있기때문에 꼭 알아야할 개념중 하나입니다!

 

우선 이개념을 알기전에 객체는 참조자료형입니다! 어떤 하나의 변수가 객체를 담고 있고 그변수에 또 다른 변수를 할당을 하면 같은 주소를 바라보고 있어 객체의 데이터를 수정하면 똑같이 수정이 됩니다. 

 

예시를 통해 알아 봅시다!!

 

1
2
3
4
5
6
7
8
9
10
11
12
// 참조자료형 객체 데이터 활용
 
const joy = {
  name : 'joycoding',
  age : 99,
 gender : 'male' 
}
const copyJoy = joy
console.log(joy === copyJoy)  // true
joy.age = 22
console.log(joy)       // {name: "joycoding", age: 22, gender: "male"}
console.log(copyJoy)   // {name: "joycoding", age: 22, gender: "male"}
cs

 

예시와 같이 새로운 변수 copyJoy에 객체 데이터를 담은 joy변수를 재할당을 하여 copyJoy와 joy는 같은 주소를 바라보고 있어서 joy.age = 22 로 변경하면 copyJoy의 age도 같이 수정 되는 사실을 알수 있습니다. 

참조자료형 객체 데이터 수정 예시

여기서 의도적으로 한거면 상관이 없습니다. 하지만 copyJoy의 age는 수정하기 싫었는데 같은 메모리 주소를 바라보고 있기때문에 joy의 데이터를 바꾸면 copyJoy의 데이터도 바뀌는 문제가 발생합니다. 그래서 이러한 문제를 해결하기 위해서 복사라는 개념이 생깁니다. 즉 얕은 복사와 깊은복사(Shallow copy, Deep copy) 입니다. 

 

그렇다면 얕은 복사와 깊은 복사는 무엇일까 ??


얕은 복사(Shallow copy)

얕은 복사는 대상의 값을 복사하는 것이 아닌 대상의 참조를 복사합니다. 쉽게 말해서 객체의 겉, 표면만 복사를 합니다. 이를 얕은 복사(shallow copy)라 부릅니다.

 

얕은 복사는 두가지의 방법이 있습니다! (더알게 된다면 추후에 또 올리겠습니다!!)

바로 Object.assign({ }, 출처객체) 메서드와 전개 연산자를 활용한 {...출처객체} 방법 입니다. 

 

얕은 복사 방법 1
Object.assign({ }, 출처객체)
1
2
3
4
5
6
7
8
9
10
11
12
13
 
const joy = {
  name : 'joycoding',
  age : 99,
  gener : 'male' 
}
 
const copyJoy = Object.assign({ }, joy)
 
console.log(joy === copyJoy)  // 다른 주소이기 때문에 false
joy.age = 22
console.log(joy)       // {name: "joycoding", age: 22, gener: "male"}
console.log(copyJoy)   // {name: "joycoding", age: 99, gener: "male"}
cs

 

자 여기서 맨위에 있는 예시와 비교하여 차이점을 발견해야 됩니다! 즉 8번줄 Object.assign({ }, joy)로 인해 맨 위의 결과 값이랑 현재 있는 결과값이 다르다라는 점을 알 수 있습니다.

 

Point1. Object.assign({  }, joy) { }는 새로운 대상의 객체를 만들어 주고 두번째 매개변수인 joy는 복사할 대상 즉 출처객체를 의미 합니다.

 

좀 더 직관적인 이미지를 통해 이해를 해봅시다!!!

얕은 복사 Object.assign 예시

 

얕은 복사 방법 2
전개연산자 {...출처객체}
1
2
3
4
5
6
7
8
9
10
11
12
13
 
const joy = {
  name : 'joycoding',
  age : 99,
  gender : 'male' 
}
 
const copyJoy = {...joy}
 
console.log(joy === copyJoy)  // false
joy.age = 22
console.log(joy)       // {name: "joycoding", age: 22, gender: "male"}
console.log(copyJoy)   // {name: "joycoding", age: 99, gender: "male"}
cs

 

추가적으로 전개연산자를 활용해서 얕은 복사가 가능합니다.

 

이두가지 방법이 얕은 복사에 많이 활용되는 예시입니다. 하지만 배열이라는 참조형 데이터를 push할 경우에는 copyJoy에 값을 변경하지 않아도 똑같이 푸쉬가 되는 경우가 있습니다. 

 

배열 데이터를 추가한 경우

 

이때 joy와 copyJoy는 같은 주소는 아니지만 age의 값은 참조자료형이 아니여서 바뀌지 않고 배열은 참조형 데이터기 때문에 메모리 주소를 공유하게 됩니다. 그래서 이러한 문제를 해결하기 위해 우리는 깊은 복사라는 개념을 알아야 합니다.

 


깊은복사 (Deep copy)

깊은 복사는 말그대로 대상의 객체안의 객체까지 전부 복사합니다. 복사가 되면 원래의 참조데이터와 연결되지 않은 객체가 만들어 집니다. 깊은 복사의 방법은 여러가지 방법이 있습니다.

 

깊은복사 방법1
재귀함수를 이용한 깊은복사

 

재귀 함수를 사용한 깊은 복사

 

깊은복사 방법2
JSON.stringify()

 

JSON.stringify()

 

이 두가지의 방법은 이런 것이 있다 라는 정도만 알면 좋겠습니다. 1번째의 재귀함수를 이용한 깊은 복사는 로직이 너무 복잡하고 가독성이 매우 떨어집니다. 2번째 JSON.stringify() 사용하는 방법은 사용하기는 쉽지만 컴퓨터가 이데이터를 처리하는 속도가 매우 떨어집니다.

 

그래서 깊은 복사를 간편하게 할 수 있는 라이브러리 Lodash 를 사용하는 것을 권장합니다.

1
2
3
4
5
6
7
8
9
10
11
12
const obj = {
  a: 1,
  b: {
    c: 2,
  },
};
 
const copiedObj = _.cloneDeep(obj);
 
copiedObj.b.c = 3
 
obj.b.c === copiedObj.b.c //false
cs

 

Lodash는 npm에서 설치해서 사용하면 됩니다. 설치가 되었는지 확인하려면 packge.json 파일에서 확인하고 링크를 걸어서 사용하면 됩니다!

 

Lodash에서 제공해주는 메서드를 사용하려면 예시의 8번줄과 같이 _(언더바) 표시를 꼭 해야됩니다!

 

Lodash는 우리가 자바스크립트로 어떤 로직을 나타낼때 쉽고 간편하게 해주는 친구입니다! 사용법은 공식 문서를 통해 확인해서 참고해보면 도움이 될 것입니다!

 

https://lodash.com/

 

Lodash

_.defaults({ 'a': 1 }, { 'a': 3, 'b': 2 });_.partition([1, 2, 3, 4], n => n % 2);DownloadLodash is released under the MIT license & supports modern environments. Review the build differences & pick one that’s right for you.InstallationIn

lodash.com

 

 

728x90
반응형
Comments