원시값과 객체의 비교

어승준·2023년 10월 21일

JS 스터디

목록 보기
19/26
post-thumbnail

📌 useEffect, useCallback, useMemo과 같은 React Hook들은 의존성배열 (dependencies)를 활용합니다. 이 의존성 배열에 들어가는 값들이 변경될 때마다 상위 Hook들이 실행됩니다. 그렇다면 의존성 배열에는 객체를 가능한 넣지 말아야 한다고 합니다. 왜 그럴까요?

  • JavaScript에서 객체는 참조값(메모리 주소)을 비교한다. 따라서 객체의 속성이 모두 같더라도, 다른 메모리 주소에 저장되어 있으면 다른 객체로 판단한다.

    const prev_obj = { count: 0 };
    const new_obj = { count: 0 };
    
    console.log(prev_obj === new_obj); // false
  • 문제가 될 수 있는 상황

    • 객체의 속성이 변하지 않는 경우
      • 해결방법 : isEqual 메소드를 통해 객체의 모든 키-값 쌍을 재귀적으로 비교 (깊은 비교)
    • 객체의 속성이 일부 변하는 경우
      • 해결방법 : 의존성 배열에는 객체의 속성이 변하는지를 감지할 수 있는 값(원시 타입의 값)을 넣어주는 것이 좋다.
    • 객체 생성 연산이 복잡한 경우
      • 객체나 배열을 만드는데 드는 비용이 큰 경우가 있다면, 매 렌더링마다 객체를 새로 생성하는 것은 성능에 좋지 않다.
      • 해결방법 : 객체를 Memoization 하는 것이다. Memoization이란, 함수의 반환값을 캐시하여 동일한 인자가 입력되었을 때, 이전에 계산된 결과를 반환하는 것을 말한다. 이를 통해 불필요한 계산을 줄일 수 있다. 이는 useMemo나 useCallback과 같은 훅을 사용하여 구현할 수 있다

📌 개발 시, 얕은/깊은 복사 쓰이는 예시와 하는 방법을 각각 설명하세요

  • 얕은 복사

    • 얕은 복사(shallow copy)는 원본 객체는 하나인 상태에서, 참조 값만 복사한다. 얕은 복사는 spread operator 또는 아래와 같은 방법으로 구현 가능하다.
    const obj = { a: 1 };
    const copyObj = obj;
    
    copyObj.a = 2;
    
    console.log(obj.a); // 2
    console.log(obj === copyObj); // true
    • obj라는 객체를 copyObj라는 객체에 복사하여 copyObj.a값을 변경하였더니 기존의 obj.a값도 같이 변경되었다.
    • 마찬가지로 두 객체를 비교해봐도 true가 나온다.
    • 이렇게 자바스크립트의 참조 타입은 얕은 복사(Shallow Copy)가 된다고 볼 수 있으며,
    • 이는 데이터가 그대로 생성되는 것이 아닌 해당 데이터의 참조 값을 전달하여 한 데이터를 공유하는 것이다.
  • 깊은 복사

    • 깊은 복사(deep copy)는 원시 값처럼 완전한 복사본을 만든다. 깊은 복사는 lodash의 cloneDeep 또는 아래와 같은 방법으로 구현 가능하다.
    const a = 1;
    const b = a;
    
    b = 2;
    
    console.log(a); // 1
    console.log(b); // 2
    console.log(a === b); // false
    • 위 코드는 변수 a 에 1을 할당하고, 변수 b 에 a 의 값을 할당한 코드이다.
    • 변수 b 의 값을 변경하여도 기존의 a 의 값은 변경되지 않는다.
    • 두 값을 비교하여도 false가 출력되며 서로의 값은 단독으로 존재한다는 것을 알 수 있다.
    • 위 예제처럼 자바스크립트의 원시 타입은 깊은 복사(Deep Copy)가 되며, 이는 독립적인 메모리에 값 자체를 할당하여 생성하는 것이라고 볼 수 있다.

📌 원시 값과 객체의 차이점은 무엇인가요?

원시 타입 (primitive type)객체 타입 (object/reference type)
변경 불가능한 값 (immutable value)변경 가능한 값 (mutable value)
할당 시변수에는 실제 값이 저장변수에는 참조 값이 저장
다른 변수에 할당시원시 값이 복사되어 전달참조 값이 복사되어 전달

📌 얕은 복사와 깊은 복사에 대해 설명해주세요.

  • 얕은 복사 는 한 단계 까지만 복사하는 것을 말하고 ➔ 참조 값을 복사
  • 깊은 복사 는 객체에 중첩되어 있는 객체 까지 복사하는 것을 말한다.
    ➔ 객체에 중첩되어 있는 객체까지 모두 복사해서 원시 값처럼 완전한 복사본을 만드는 복사

📌 불변성에 대해서 설명하고 불변성이 가져다 주는 효과에 대해서 말해주세요.

  • 불변성(Immutability)란 말그대로 변하지 않는 것을 의미한다. 불변 데이터는 한번 생성되고나면 그 뒤에는 변할수 없다.
  • 자바스크립트에는 원시 타입(primitive type)으로는
    Boolean,
    String
    Number
    Null
    undefined
    Symbol
    이 있으며 이 원시 타입은 불변한다.
  • 불변성을 지키지 않는다면, 사용할 데이터가 어디서 어떻게 바뀌어가는지 흐름을 쫓아가기 어렵고, 이는 곧 예기치 못한 side effects나 버그로 이어지게 만든다.
  • 불변성을 지켜 명시적으로 작성된 코드는 다른 개발자가 코드를 보았을 때도 내가 모르는 어딘가에서 데이터가 변화했을거야! 라는 불필요한 의심없이 코드를 읽는 그대로 흐름을 따라가면서 이해할 수 있도록 돕는다.
  • 따라서 불변성을 지키면서 데이터를 변화시킨다면, 예상가능하고 신뢰할 수 있는 코드가 될 수 있다.
profile
鈍筆勝聰(둔필승총) : '둔한 붓이 총명함을 이긴다' (서툴더라도 기록으로 남기는 것이 사람의 기억보다 훨씬 오래 보전된다) - 정약용

0개의 댓글