[TIL] 2020. 06. 20. ShallowCopy_DeepCopy

달밤·2020년 6월 20일
1

TIL

목록 보기
46/110
post-thumbnail

오늘 배운 것

Copy in JavaScript

자바스크립트에서 배열이나 객체를 복제할 때 고려해야 할 얕은 복제(Shallow Copy)깊은 복제(Deep Copy)에 대해 알아본다.

  • 우선 자바스크립트의 Data Type에는 Primitive TypeReference Type이 있다는 것을 알고 있을 것이다.

  • Primitive Type과는 달리 Reference Type를 변수에 할당하면 데이터를 자체를 저장되지 않고 않고, 그 데이터에 대한 참조가 저장된다.

  let arr1 = [];
  let arr2 = [];
  
  console.log(arr1 === arr2)	//false
  //겉보기에는 같은 배열 같아보인다.
  //하지만 이 경우 arr1과 arr2가 참조하고 있는 값이 다르기 때문에,
  //arr1과 arr2는 다르다.
  
  arr1.push(1)
  //따라서 arr1을 변형시켜도
  
  console.log(arr2) // []
  //arr2는 영향을 받지 않는다.
  
  let x = [1, 2, 3, 4];
  let y = x;	//변수 x에 저장된 배열 객체의 참조가 y변수에 할당되었다.
  y.push(5);	//y 배열에 5를 푸시한다.
  
  console.log(x);	//[1,2,3,4,5]
  //x와 y의 참조 값이 같다.
  //따라서 y를 변형시키면, x 또한 변화한다.
  //즉 x===y이다.
  
  //이는 x와 y가 바라보는(참조하는) 값이 같기 때문에 이런현상이 나타난 것이다. 
  //x 배열이 참조하는 값의 데이터만을 복제해 y에 할당할 수는 없을까?
  //그렇게 될 수만 있다면 y를 변형시켜도 x에 영향을 미치지 않게 될 것이다.
  • 위에 대한 이해를 바탕으로 Shallow CopyDeep Copy에 대해 알아보도록 한다.

  • 이를 설명하기 위해 아래에 소개된 메소드들은 하나의 예시일 뿐이다. Shallow CopyDeep Copy는 하나의 개념일 뿐, 이를 구현 하는 방식은 다양할 수 있다.

1. Shallow Copy

말 그대로 얕게 복제하는 것을 의미한다.

let arr1 = [[1],2];
let arr2 = Object.assign([], arr1)	//arr1 배열을 복사 
//arr1을 단순히 arr2에 할당하는게 아니라,
//Object.assign() 메소드를 이용해 arr1의 데이터를 복사해 arr2에 할당해 주었다.

console.log(arr1 === arr2)	//false
//값이 false가 나오는 것을 보니
//arr1과 arr2가 참조하는 값이 다른 모양이다.
//따라서 이제 arr2에 변형을 가해도 arr1에는 어떠한 영향도 주지 않게 된다.

//이 방식은 배열이나 객체를 변수에 단순할당했을 때의 문제점을 모두 해결해주었을까?
//아쉽게도 그렇지는 않다.
console.log(arr1[0] === arr2[0]) //true
//값이 true가 나왔다.
//즉 arr1[0] 배열과 arr2[0] 배열의 참조 값이 같다는 것이다.

//Objecet.assign()메소드의 경우
//새로운 객체에 원복 객체의 프로퍼티의 값을 정확히 복사한다.
//하지만 만약 프로퍼티의 값이 객체(배열) 형태라면, 객체의 참조를 복사한다.
//따라서 얕은 깊이에서 복제는 작동하지만,
//완벽한 복제는 아니라서 좀 더 깊이 들어가면 같은 참조 값을 공유하는 현상이 발생한다.

//이런 식의 Copy를 Shallow Copy라고 한다.

2. Deep Copy

Shallow Copy와는 다르게 모든 깊이에서 복제하는 것을 의미한다.

let arr1 = [[1],2];
let arr2 = JSON.parse(JSON.stringify(arr1));
//우선 JSON.stringify() 메소드를 이용해 
//JavaScript 객체를 JSON 문자열로 변형시켜준다.
//이제 arr1의 참조는 사라지고, 
//arr1의 데이터는 JSON 문자열 형식으로 변환된다.

//JSON.parse()메소드를 이용해 
//JSON 문자열을 다시 JavaScript에 해당하는 객체로 변환한다.
//그 객체가 arr2에 할당된다.

console.log(arr1 === arr2) //false
console.log(arr1[0] === arr2[0]) //false

//모든 깊이에서의 복제가 이루어졌다.
//이런 식의 Copy를 Deep Copy라고 한다.
profile
다 늦은 밤, 달밤의 개발일기

0개의 댓글