enum이 필요한 이유 / JS에서 enum 타입 구현하기
책의 장르를 검사해서 만약 science라면 특정 문구를 출력한다고 하자.
그런데 아래와 같이 대소문자가 다르거나 오타가 발생한다면?
let genre = "Science";
if(genre === "science") {
console.log("I love it!");
}
이럴 때 필요한 게 바로 enum이다.
enum의 장점은
- 값에 일관성이 있고, IDE 자동완성의 도움을 받을 수 있어 오타를 최소화 할 수 있다.
- 값이 변경되더라도 enum 값만 변경하면 되기 때문에 리팩토링 비용을 최소화할 수 있다.
- 비슷한 집합끼리 묶어서 보관할 수 있으며, 한 집합 안에서만 이름이 중복되지 않으면 된다.
하지만 JS는 Enum(열거형) 타입을 지원하지 않는다. 그래도 enum처럼 작동하도록 구현은 할 수 있다.
다음 세 가지 방법을 비교해보자.
const와 Object로 구현
const genres = {
SCIENCE: 0,
MATH: 1,
NOVEL: 2,
COOK: 3
};
우리가 Object로 자주 구현하는 형태이다. 이렇게 상수로 만들어 놓으면 필요할 때 간단히 genres.MATH로 값을 참조할 수 있다.
문제점
1. enum값과 일반 값이 구분이 안된다.
genre에 genres.MATH가 들어갔을 때와 의도치 않게 1이라는 값이 들어갔을 때의 차이가 없다.
// let genre = genres.MATH;
let genre = 1;
if(genre === genres.MATH) {
console.log('This is a math book);
}
2. const로 선언했다고 해도 내부의 key-value 값은 변경이 가능하므로 완전히 불변은 아니다.
Symbol + Object.freeze()
1. Symbol
enum값과 일반 값이 구분이 안 되는 문제를 해결하기 위해 Symbol 타입을 사용한다. Symbol()로 생성한 값은 유일하므로 위에서처럼 우연히 변수에 상수에 할당된 것과 같은 값이 들어가 문제가 생기는 일을 방지할 수 있다.
const genres = {
SCIENCE: Symbol(0),
MATH: Symbol(1),
NOVEL: Symbol(2),
COOK: Symbol(3),
};
let genre = genres.MATH;
switch(genre) {
case genres.SCIENCE:
console.log('I love science');
break;
case genres.MATH:
console.log('I love MATH');
break;
//...
}
2. Object.freeze()
Object의 프로퍼티 값이 변경 가능하다는 문제는 Object.freeze()로 해결할 수 있다. Object.freeze()는 객체를 동결해서 더이상의 프로퍼티의 추가, 변경, 삭제를 막는다.
const genres = Object.freeze({
SCIENCE: Symbol(0),
MATH: Symbol(1),
NOVEL: Symbol(2),
COOK: Symbol(3),
});
let genre = genres.MATH;
switch(genre) {
case genres.SCIENCE:
console.log('I love science');
break;
case genres.MATH:
console.log('I love MATH');
break;
//...
}
// genres.MATH = "math"로 바꾸려고 하면 error를 throw한다.
Reference
https://codechacha.com/ko/javascript-enum/
https://sewonzzang.tistory.com/28
'Front-end > Javascript' 카테고리의 다른 글
[JS] 랜덤 숫자 생성법 이해하기 | Math.random() (0) | 2023.09.04 |
---|---|
[JS] 올림, 반올림, 내림 (ceil, round, floor) / 특정 자리수까지 0 채우기 (0) | 2022.08.08 |
[JS] onInput 이벤트 - 입력한 글자 실시간으로 화면에 출력하기 (0) | 2022.02.22 |
[JS] prototype 참고글 (0) | 2021.09.26 |
[JS] String 오브젝트에 굳이 toString()이 있는 이유 (0) | 2021.09.25 |