깊은 복사 얕은 복사 깊은 복사 얕은 복사 깊은 복사 얕은 복사 깊은 복사 얕은 복사 깊은 복사 얕은 복사

hojoon·2023년 8월 3일
0

자바스크립트

목록 보기
6/14

복사?

무슨 코드일까??

간단하게 설명해보자면

  1. 백엔드에서 로봇이 가지고 있는 지도 데이터가 있고 지도에는 각각의 목적지가 저장되어 있다.
  2. 리덕스 thunk로 api에 요청을 보내고 상태, 데이터는 리덕스로 관리한다.

    (여러개의 맵 데이터가 있고 사용자가 선택한 맵의 목적지들만 가져오는중)
  3. setDestinationsPlus는 그럼 뭘까?? 리덕스 스토어에서 데이터를 가져와서 쓰는데 왜 useState로 배열안에 다시 값을 넣어주고 props 내려주기로 목적지에 대한 데이터를 다루고 있는데 주석을 보면 무한루프를 피하기 위해서라고 적혀있다. 아마 무한루프 문제가 있었나보다
  4. 여튼 다시 회사 프로덕트의 구조를 설명해보자면 프론트엔드 - nodejs(로봇백엔드와의 브릿지역할) - Robot이다. 좀 특이한 구조인데 즐겨찾기 기능을 추가해야 하는일이 있었다.
  5. 로봇은 따로 사용자가 즐겨찾기한 목적지에 대한 데이터를 가지고 있지 않고 웹에서 NodeJS와 프론트에서 따로 만들어서 관리해야함

이런 상황이 있었다.

이 글을 쓰는 이유

 setDestinationsPlus(
  destinations.map((d) => ({
    ...d,

리덕스를 쓰는데 리덕스로 상태 관리를 안 하고 useState에 다시 넣어줘서 프롭스를 계속 내려주는데 이 한 줄짜리 코드를 몇 시간 동안 못 찾아서 짜증났었음 ㅋㅋㅋㅋ

(하튼 그래서 destinations 어디서 주는지 못찾아서 어디서 주고 있는지 물어봤다가 전개연산자도 모르고 얕은 복사 깊은 복사는 아냐고 창피주더라 )
(ㅈㄴ 억울했음..!)

그래서 제대로 다시 자바스크립트 깊은 복사 얕은 복사 공부한다.

나름 전개연산자 달인이라고 혼자 생각했었음 ㅋㅋ

어제 카카오 시니어 개발자분이 블로그 글을 쓸때 다른 사람 글을 베껴오는게 아니라 내가 이해하고 생각한대로 글을 적는게 중요하다고 했음. 그래서 내맘대로 적어봄

일단 요약

  • 깊은 복사 : 원본의 영향을 주지 않고 값 전체를 복사해옴

  • 얕은 복사 : 복사는 하는데 값이 변경되면 서로 같은 메모리 주소를 바라보고 있기때문에 영향을 서로 받음

변수의 타입

  • 원시타입과 참조타입이 있다.
  • 원시타입은 값자체가 담김
  • 참조타입은 값이 아니라 값을 담고있는 메모리주소가 담겨서 메모리 주소를 바라봄

이런것들 공부하다 보면 가끔 재밌다. 프로그래밍은 진짜 모든 개념이 다 얽혀있고 변수의 타입에서만 생각나는 개념들은 호이스팅, undefined, const 등등

공부하다가 새롭게 알게 된거라 퍼옴..!
출처 : https://hanamon.kr/javascript-%EB%B3%80%EC%88%98%EC%9D%98-%ED%83%80%EC%9E%85-%EC%9B%90%EC%8B%9C%ED%98%95%EA%B3%BC-%EC%B0%B8%EC%A1%B0%ED%98%95/

여튼 변수의 타입이라는 자바스크립트만의 특징이 있다.

여튼 다시 천천히 깊은 복사와 얕은 복사에 대해 알아보자면

  • 변수는 값의 위치(주소)를 기억하는 메모리 공간인데, 값의 위치란 값이 위치하고 있는 메모리 상의 주소(address)를 의미한다. (재밌다)

출처 : https://pozafly.github.io/javascript/shallo-copy-and-deep-copy/

아 근데 요약이 끝이다. 더 알아야 할게 있나??
깊은 복사는 var a = 10, var b = 10

a === b (true)
b = 20

b 에다가 20을 줘도 a에는 영향이 없다. b에는 다른 메모리주소를 할당해준다.

어제 딥다이브 읽으면서 공부했던 내용이랑 또 연관이 있어서 재밌다.

그럼 객체는 왜 영향을 받는지 생각해보면

우선 객체 그 자체의 값을 바꾼 건 아니고 프로퍼티를 바꾼 경우 : 말 그대로 객체가 바라보는 주소 자체를 바꾼 게 아니라 프로퍼티가 바라보고 있는 주소를 바꿨기 때문이다.

그러면 객체를 바꾸려면 ?? 전체 프로퍼티를 바꿔야 하는데 방법이 세가지가 있다고 함

  • lodash
  • 재귀함수
  • JSON.parse(성능에 안좋다고 함 ) 난 성능에 민감한 사람임

여튼 세가지 방법이 있는데 이렇게 해야 깊은 복사가 일어남

예전에는 이거 몰라서 노래 검색 기능 구현하면서 대소문자를 구분하지 않고 노래 검색을 하고 싶었는데 자꾸 원본 객체에 영향을 줘서 고생했던 적이 있다.
그 당시에는 필요한 속성값들만 따로 빼고 고유한 id를 부여해서 새로운 객체를 만들어버려서 처리했음!

끝.!

추가사항!!

자바스크립트 깊은 복사 지원하는 API 생김

  • 스터디 팀원분이 알려주셨다.
const myDeepCopy = structuredClone(myOriginal);

기능 및 제한 사항

Structured cloning은 JSON.stringify()의 많은 (전부는 아니지만) 단점을 해결합니다. 구조적 복제는 순환되는 데이터 구조를 처리할 수 있고, 내장 데이터 타입을 지원할 수 있으며 일반적으로 더 강력하고 더 빠릅니다.

그러나 여전히 몇 가지 제한 사항이 있습니다.

  • 프로토타입 : structuredClone()를 클래스 인스턴스와 함께 사용 하는 경우, strucuted cloning이 객체의 프로토타입 체인을 폐기하므로 반환 값은 일반 객체가 됩니다.
  • 함수 : 객체에 함수가 포함되어 있으면 폐기됩니다.
  • 복제 불가 : 일부 값, 특히 Error와 DOM 노드는 구조화된 복제가 불가능합니다. 그것은 structuredClone() 예외 에러(throw)의 원인이 됩니다.
    이러한 제한 사항이 당신이 사용하려는 상황에 해당한다면 Lodash와 같은 라이브러리는 여전히 다른 깊은 복사 알고리즘을 custom하여 적용할 수 있도록 제공하고 있습니다.

성능

요약 : 복사본을 생성하기 위한 기본 접근 방식으로 정해놓아도 손색없습니다.

출처(https://velog.io/@seonja/StructuredClone%EC%9D%84-%EC%82%AC%EC%9A%A9%ED%95%98%EC%97%AC-JavaScript%EC%97%90%EC%84%9C-%EA%B9%8A%EC%9D%80-%EB%B3%B5%EC%82%AC)

끝! 감사합니다~ 굿~바이`

profile
프론트? 백? 초보 개발자의 기록 공간

0개의 댓글