본문 바로가기
2023/멋쟁이사자처럼_FE5

[JS] 얕은 복사와 깊은 복사에 대해서 설명해보세요.

by ye-jji 2023. 5. 2.
  1. 데이터 타입
    • 원시타입 : 변수에 주소 할당, 값을 재할당 하는 것은 메모리에서 데이터를 바꾸는 것이 아니라 메모리 주소를 바꿈 그래서 원시타입 데이터는 불변성을 가짐
    • 객체타입 : 프로퍼티 키와 프로퍼티 값이 각각 메모리 주소로 메모리에 저장되어 있고 그 메모리 주소로 가면 프로퍼티 키에 대한 메모리 주소가 또 있음 그래서 중간 주소를 변경하면 값이 변경됨 그래서 참조형 데이터라 불리고 변경이 가능함
  2. 객체타입에서 복사
    1. 얕은 복사
      1. 바로 아래 단계 값만 복사
      2. 중첩된 객체에서 참조형 데이터가 저장된 프로퍼티를 복사할 때 그 주솟값만 복사한다는 의미
      3. 즉, 사본을 바꾸면 원본도 바뀜
    2. 깊은 복사
      1. 내부의 모든 값들을 하나하나 찾아서 전부 복사하는 방법
      2. 깊은 복사를 수행하는 함수
      3. let copyObjectDeep = function(target){ let result = {}; if(typeof target === 'object' && target !== null){ // target이 객체인 경우 for(let prop in target){ result[prop] = copyObjectDeep(target[prop]); } } else { // target이 객체가 아닌 경우 result = target; } return result; };
      4. hasOwnProperty 메서드를 활용해 프로토타입 체이닝을 통해 상속된 프로퍼티를 복사하지 않게끔 할 수 있음
      5. 객체를 JSON문법으로 표현된 문자열로 전환했다가 다시 JSON 객체로 바꾸는 것→ But, 메서드(함수)나 숨겨진 프로퍼티인 __proto__나 getter/setter 등과 같이 JSON으로 변경할 수 없는 프로퍼티들은 모두 무시. (undefined, Infinity, -infinity, NaN 등은 JSON.stringify()를 통해 전달 불가능)→ httpRequest로 받은 데이터를 저장한 객체를 복사할 때 등 순수한 정보만 다룰 때 활용하기 좋음
      6. →객체 안에 순환 참조가 있을 경우 무한 루프에 빠지므로 주의가 필요(깊은 복사 수행 시 상황에 맞는 방법을 선택해야함)
      7. → 단순함에도 잘 동작함
  3. 결론
  4. 어떤 객체를 복사하는 경우, 객체 내부의 모든 값을 복사해서 완전히 새로운 데이터를 만들고자 할 때, 객체의 프로퍼티 중에서 그 값이 기본형 데이터일 경우에는 그대로 복사하면 되지만 참조형 데이터는 다시 그 내부의 프로퍼티들을 복사해야함. 이 과정을 참조형 데이터가 있을 때마다 재귀적으로 수행해야만 비로소 깊은 복사가 됨

참고 : 🦎 137p~153p / 🐯 20p~29p