Object.freeze

ljjunh·2024년 11월 25일

clean-code-javascript

목록 보기
33/38
post-thumbnail

객체의 불변성은 안전한 프로그래밍을 위해 매우 중요하다. 자바스크립트는 이를 위해 Object.freeze라는 내장 메서드를 제공하는데, 이름 그대로 객체를 '얼려서' 변경할 수 없게 만든다.

기본적인 Object.freeze 사용 🧊

객체를 동결시켜 속성 추가, 수정, 삭제를 방지

const STATUS = Object.freeze({
    PENDING: 'PENDING',
    SUCCESS: 'SUCCESS',
    FAIL: 'FAIL'
});

// ❌ 수정 시도
STATUS.NEW_PROP = 'P2';  // 작동하지 않음
STATUS.PENDING = 'P';    // 작동하지 않음
delete STATUS.FAIL;      // 작동하지 않음

console.log(STATUS); // { PENDING: 'PENDING', SUCCESS: 'SUCCESS', FAIL: 'FAIL' } 
// ✅ 동결 확인
console.log(Object.isFrozen(STATUS));  // true

여기까지는 잘 작동한다. 하지만 중첩된 객체에 사용할 때 문제가 생긴다.

Object.freeze의 한계 🚫

const STATUS = Object.freeze({
    PENDING: 'PENDING',
    SUCCESS: 'SUCCESS',
    FAIL: 'FAIL',
    OPTIONS: {
        GREEN: 'GREEN',
        RED: 'RED'
    }
});

// 중첩된 객체는 여전히 수정 가능
STATUS.OPTIONS.GREEN = 'G'
STATUS.OPTIONS.YELLOW = 'Y'
delete STATUS.OPTIONS.RED

console.log(STATUS.OPTIONS); // { GREEN: 'G', YELLOW: 'Y' }

왜 이런 일이 발생할까? Object.freeze는 "얕은 동결(shallow freeze)"만 수행하기 때문이다. 즉, 객체의 직접적인 속성만 동결하고 중첩된 객체는 동결하지 않는다.

해결 방법 💡

1. 직접 깊은 동결 함수 만들기

function deepFreeze(targetObj) {
    // 1. 객체를 순회
    // 2. 값이 객체인지 확인
    // 3. 객체면 재귀
    // 4. 그렇지 않으면 Object.freeze
    return Object.freeze(targetObj);
}

2. 라이브러리 사용

lodash와 같은 대중적인 유틸리티 라이브러리 활용

3. TypeScript 사용

readonly 키워드로 컴파일 타임에 불변성 보장

실제 프로젝트에서는 팀의 상황에 맞는 방법을 선택하면 된다. 특히 TypeScript를 사용하는 프로젝트라면 readonly를 활용하는 것이 좋은 선택이다.
결론적으로, Object.freeze는 매우 유용하지만 깊은 동결이 필요한 경우에는 추가적인 처리가 필요하다. 팀 프로젝트에서는 이러한 제한사항을 이해하고, 필요에 따라 deepFreeze를 구현하여 사용하는 것이 안전하다 💪

profile
Hello

0개의 댓글