24. Symbol : 유일무이한 식별자
2026년 4월 14일
💎 1. 심볼(Symbol)이란?
심볼은 **'유일무이한 식별자'**를 만들기 위해 사용되는 원시형 데이터입니다.
-
특징: 한 번 만들어진 심볼은 세상에 단 하나뿐입니다. 설령 이름(설명)이 같더라도 서로 다른 값으로 취급됩니다.
-
생성 방법:
Symbol()함수를 호출합니다.JavaScriptlet id1 = Symbol("id"); let id2 = Symbol("id"); alert(id1 == id2); // false! 이름은 같지만 서로 다른 심볼입니다.
🛡️ 2. 심볼의 주요 특징
① 문자형으로 자동 형 변환되지 않음
자바스크립트의 다른 값들과 달리 심볼은 alert() 등에 넣어도 자동으로 문자열로 변하지 않습니다. 이는 심볼이 가진 '유일성'을 보호하기 위한 장치입니다.
- 출력이 필요할 땐:
id.toString()혹은id.description을 사용하세요.
② 객체의 '숨김' 프로퍼티 (Hidden Property)
심볼을 객체의 키로 사용하면, 외부 코드에서 함부로 접근하거나 덮어쓸 수 없는 **'비밀 공간'**을 만들 수 있습니다.
💡 왜 문자열 키 대신 심볼을 쓰나요?
서드파티 라이브러리에서 가져온 객체에 나만의 식별자를 붙이고 싶을 때, 문자열
"id"를 쓰면 라이브러리 내부의"id"와 충돌할 수 있습니다. 하지만 심볼을 쓰면 이름이 같아도 절대 충돌하지 않습니다.
📋 3. 객체 리터럴과 반복문에서의 동작
객체 리터럴에서 사용하기
심볼을 키로 쓸 때는 반드시 **대괄호 []**를 사용해야 합니다.
let id = Symbol("id"); let user = { name: "John", [id]: 123 // 대괄호가 없으면 문자열 "id"가 되어버립니다. };
반복문에서의 배제
심볼형 키는 for..in 루프나 Object.keys()에서 완전히 무시됩니다.
- 이점: 라이브러리가 객체를 순회할 때 우리가 숨겨둔 심볼 프로퍼티를 건드리지 않게 보호합니다.
- 주의:
Object.assign은 심볼도 함께 복사합니다. (객체 복제 시에는 모든 데이터가 필요하다고 가정하기 때문입니다.)
🌐 4. 전역 심볼 (Global Symbol)
애플리케이션 곳곳에서 이름이 같으면 같은 값으로 취급되는 심볼이 필요할 때 사용합니다.
Symbol.for(key): 전역 레지스트리에서 해당 이름의 심볼을 찾습니다. 없으면 새로 만듭니다.Symbol.keyFor(sym): 전역 심볼을 넣어 그 이름을 다시 가져옵니다.
🎙️ 기술 면접 대비 (Interview Questions)
Q1. 심볼을 사용하는 가장 큰 실무적인 이유는 무엇인가요? (중급)
답변: **'프로퍼티 키 충돌 방지'**입니다. 특히 대규모 프로젝트에서 여러 라이브러리가 하나의 객체를 공유할 때, 문자열 키를 쓰면 서로 같은 이름을 사용해 데이터를 덮어쓸 위험이 있습니다. 심볼은 유일성이 보장되므로 안전하게 전용 식별자를 추가할 수 있습니다.
Q2. 심볼형 키는 완벽하게 숨겨지나요? (심화)
답변: 완전히 숨겨지지는 않습니다.
Object.getOwnPropertySymbols(obj)나Reflect.ownKeys(obj)를 사용하면 심볼형 키를 찾아낼 수 있습니다. 하지만 일반적인 루프나 메서드에서는 배제되므로, **'의도치 않은 접근'**을 막는 데는 충분한 효과가 있습니다.
Q3. 시스템 심볼(System Symbol)이란 무엇인가요? (심화)
답변: 자바스크립트 내부 동작을 조절하기 위해 미리 정의된 심볼들입니다. 예를 들어
Symbol.iterator를 구현하면 객체를 반복 가능하게 만들 수 있고,Symbol.toPrimitive를 쓰면 객체가 숫자로 변할 때의 동작을 정의할 수 있습니다.
💡 Tech Lead의 한 줄 인사이트
심볼은 일상적인 코딩에서는 자주 쓰이지 않을 수 있지만, 라이브러리 제작자나 대규모 아키텍처 설계자에게는 필수적인 도구입니다. 내가 만든 코드가 다른 사람의 코드와 섞여도 안전하길 원한다면 심볼을 기억하세요.
요약
Symbol은 원시형 데이터로, 유일무이한 식별자를 만드는 데 사용됩니다.
Symbol()을 호출하면 심볼을 만들 수 있습니다. 설명(이름)은 선택적으로 추가할 수 있습니다.
심볼은 이름이 같더라도 값이 항상 다릅니다. 이름이 같을 때 값도 같길 원한다면 전역 레지스트리를 사용해야 합니다. Symbol.for(key)는 key라는 이름을 가진 전역 심볼을 반환합니다. key라는 이름을 가진 전역 심볼이 없으면 새로운 전역 심볼을 만들어줍니다. key가 같다면 Symbol.for는 어디서 호출하든 상관없이 항상 같은 심볼을 반환해 줍니다.
심볼의 주요 유스 케이스는 다음과 같습니다.
-
객체의 ‘숨김’ 프로퍼티 – 외부 스크립트나 라이브러리에 ‘속한’ 객체에 새로운 프로퍼티를 추가해 주고 싶다면 심볼을 만들고, 이를 프로퍼티 키로 사용하면 됩니다. 키가 심볼인 경우엔
for..in의 대상이 되지 않아서 의도치 않게 프로퍼티가 수정되는 것을 예방할 수 있습니다. 외부 스크립트나 라이브러리는 심볼 정보를 갖고 있지 않아서 프로퍼티에 직접 접근하는 것도 불가능합니다. 심볼형 키를 사용하면 프로퍼티가 우연히라도 사용되거나 덮어씌워 지는 걸 예방할 수 있습니다.이런 특징을 이용하면 원하는 것을 객체 안에 ‘은밀하게’ 숨길 수 있습니다. 외부 스크립트에선 우리가 숨긴 것을 절대 볼 수 없습니다.
-
자바스크립트 내부에서 사용되는 시스템 심볼은
Symbol.*로 접근할 수 있습니다. 시스템 심볼을 이용하면 내장 메서드 등의 기본 동작을 입맛대로 변경할 수 있습니다. iterable 객체에선Symbol.iterator를, 객체를 원시형으로 변환하기에선Symbol.toPrimitive이 어떻게 사용되는지 알아보겠습니다.
사실 심볼을 완전히 숨길 방법은 없습니다. 내장 메서드 Object.getOwnPropertySymbols(obj)를 사용하면 모든 심볼을 볼 수 있고, 메서드 Reflect.ownKeys(obj)는 심볼형 키를 포함한 객체의 모든 키를 반환해줍니다. 그런데 대부분의 라이브러리, 내장 함수 등은 이런 메서드를 사용하지 않습니다.