상수 데이터 불변하게 관리하기

taeyooooon·2023년 11월 11일
0
post-thumbnail

개요

우테코 미션이 끝난 뒤 다른 사람들 코드를 보는데 몇몇분들이 상수를 const로 선언하면서 Object.freeze()로 상수를 관리하고 있었습니다.
저는 아래와 같이 선언해서 사용하고 있었는데, 왜 Object.freeze()를 사용하는지 알아보았습니다.

예시 코드


export const ERROR_PREFIX = '[ERROR]';

export const ERROR = {
  participant: `${ERROR_PREFIX} 참가자 입력값을 확인하세요.`,
  repeatNumber: `${ERROR_PREFIX} 시도할 횟수 입력값을 확인하세요.`,
};

상수 데이터 변경

원시타입 상수

const로 선언한 원시타입 상수의 경우 아래처럼 재할당이 불가능 하지만

ERROR_PREFIX = 'HELLO'
// TypeError: Assignment to constant variable.

참조타입 상수

아래처럼 참조타입인 배열 또는 객체 는 자유롭게 할당된 값을 변경할 수 있습니다.
메모리 주소값에 할당된 주소는 바뀌지 않고 할당된 값만 변경했기 때문이죠.

console.log(ERROR.participant);
// `[ERROR] 참가자 입력값을 확인하세요.`

PROMPT.joinList = "수정";

console.log(ERROR.participant);
// `수정`

Object.freeze()

이러한 상황에서 Object.freeze() 를 사용하면 위와 같이 불변성에 위반되는 행위를 예방할 수 있습니다.

const ERROR_PREFIX = '[ERROR]';

export const ERROR = Object.freeze({
  participant: `${ERROR_PREFIX} 참가자 입력값을 확인하세요.`,
  repeatNumber: `${ERROR_PREFIX} 시도할 횟수 입력값을 확인하세요.`,
  array : [1, 2, 3]
});

ERROR_PREFIX = 'HELLO'; 
// TypeError: Assignment to constant variable.
ERROR.participant = '수정'; 
// TypeError: Cannot assign to read only property 'participant' of object '#<Object>'

그러나 Object.freeze() 는 얕은 동결, 즉 depth 1 까지만 얼려주기 때문에 depth 2 이상의 데이터는 여전히 수정이 가능합니다.

console.log(ERROR.array)
// [1, 2, 3]
ERRPR.array.push(4)
console.log(ERROR.array)
// [1, 2, 3, 4]

deepFreeze() 로 깊은 동결하기

불변성을 확보하기 위해 아래 예시와 같이 depth 2 이상의 데이터도 동결하는 함수를 직접 만들어 사용합니다.

function deepFreeze(object) {
  Object.keys(object).forEach((key) => {
    if (typeof object[key] === "object" && object[key] !== null) {
      deepFreeze(object[key]);
    }
  });

  return Object.freeze(object);
}

null 체킹을 하는 이유는 typeof null 의 결과가 object이기 때문

최종결과

아래처럼 deepFreeze함수를 이용해 재귀적으로 동결시켜주면 원하던 결과인 depth가 깊은 데이터도 불변하게 유지할 수 있습니다!

export const ERROR = deepFreeze({
  participant: `${ERROR_PREFIX} 참가자 입력값을 확인하세요.`,
  repeatNumber: `${ERROR_PREFIX} 시도할 횟수 입력값을 확인하세요.`,
  array: [1, 2, 3],
});

console.log(ERROR.array);
// [1, 2, 3]
ERROR.array.push(4);
console.log(ERROR.array);
// TypeError: Cannot add property 3, object is not extensible
profile
응애🐣 프론트엔드

0개의 댓글

관련 채용 정보