[JavaScript]
기초
- [JS] Js기초
- [JS] Js기초 변수
- [JS] Js기초 자료형
- [JS] Js기초 형변환
- [JS] Js기초 연산자
- [JS] Js기초 반복문
- [JS] Js기초 switch
- [JS] Js기초 function
- [JS] Js기초 객체
- [JS] Js기초 배열
중급
- [JS] Js중급 호이스팅(Hoisting)과 TDZ(Temporal Dead Zone)
- [JS] Js중급 생성자함수
- [JS] 객체 메소드(Object methods), 계산된 프로퍼티(Computed property)
- [JS] 심볼(Symbol)
- [JS] WeakMap WeakSet
- [JS] 숫자, 수학 method (Number, Math)
- [JS] 문자열 메소드(String methods)
- [JS] 배열 메소드(Array methods)
- [JS] 구조 분해 할당 (Destructuring assignment)
- [JS] 매개변수 리스트와 전개 문법(Rest parameters and spread syntax)
- [JS] 클로저(Closure)
- [JS] setTimeout / setInterval
- [JS] call / apply / bind
- [JS] 상속, 프로토타입(Prototype)
- [JS] 클래스(Class)
- [JS] 클로미스(Promise)
- [JS] 비동기 처리(Async/Await)
- [JS] Generator
- [JS] 메모리 릭(Memory Leak)
심볼(Symbol)은 유일한 식별자를 만들 때 사용하는 특별한 타입이야! 🎯
1. 심볼 기본
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| // 심볼 만들기
const mySymbol = Symbol();
const mySymbol2 = Symbol("설명"); // 설명을 추가할 수 있음
// 각 심볼은 유일함!
const sym1 = Symbol("test");
const sym2 = Symbol("test");
console.log(sym1 === sym2); // false
// 객체의 프로퍼티 키로 사용
const obj = {
[sym1]: "값1",
[sym2]: "값2",
};
console.log(obj[sym1]); // "값1"
console.log(obj[sym2]); // "값2"
|
2. Symbol.for() - 전역 심볼
1
2
3
4
5
6
7
8
9
10
11
12
| // 전역 심볼 레지스트리에서 심볼 생성/검색
const globalSym1 = Symbol.for("myKey");
const globalSym2 = Symbol.for("myKey");
console.log(globalSym1 === globalSym2); // true
// 심볼의 키 가져오기
console.log(Symbol.keyFor(globalSym1)); // "myKey"
// 일반 심볼은 키를 가져올 수 없음
const localSym = Symbol("myKey");
console.log(Symbol.keyFor(localSym)); // undefined
|
3. 숨겨진 프로퍼티로 사용
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
| const LEVEL = Symbol("level");
const HP = Symbol("hp");
class Game {
constructor() {
this[LEVEL] = 1; // 심볼을 프로퍼티 키로 사용
this[HP] = 100;
}
powerUp() {
this[LEVEL]++;
this[HP] += 50;
console.log(`파워업! 레벨: ${this[LEVEL]}, HP: ${this[HP]}`);
}
}
const game = new Game();
game.powerUp(); // "파워업! 레벨: 2, HP: 150"
// 심볼 프로퍼티는 일반적인 방법으로는 보이지 않음
console.log(Object.keys(game)); // []
console.log(Object.getOwnPropertyNames(game)); // []
// 심볼 프로퍼티 보기
console.log(Object.getOwnPropertySymbols(game)); // [Symbol(level), Symbol(hp)]
|
4. 내장 심볼 (Well-known Symbols)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
| class Collection {
constructor() {
this.items = [];
}
// Symbol.iterator를 구현하여 반복 가능하게 만듦
[Symbol.iterator]() {
let index = 0;
return {
next: () => {
if (index < this.items.length) {
return { value: this.items[index++], done: false };
}
return { done: true };
},
};
}
// Symbol.toPrimitive로 형변환 동작 정의
[Symbol.toPrimitive](hint) {
if (hint === "number") {
return this.items.length;
}
return this.items.join(", ");
}
}
const collection = new Collection();
collection.items = ["🍎", "🍌", "🍊"];
// iterator 사용
for (let item of collection) {
console.log(item); // 🍎, 🍌, 🍊
}
// toPrimitive 사용
console.log(+collection); // 3
console.log(`${collection}`); // "🍎, 🍌, 🍊"
|
5. 실전 예제: 프라이빗 프로퍼티 구현
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
| const privateProps = new WeakMap();
class Player {
constructor(name) {
// 프라이빗 데이터 저장
privateProps.set(this, {
name: name,
hp: 100,
mp: 50,
});
}
get status() {
const props = privateProps.get(this);
return `
이름: ${props.name}
HP: ${"❤️".repeat(props.hp / 20)}
MP: ${"💙".repeat(props.mp / 10)}
`;
}
useSkill(skillName) {
const props = privateProps.get(this);
const mpCost = {
파이어볼: 30,
힐링: 20,
};
if (props.mp >= mpCost[skillName]) {
props.mp -= mpCost[skillName];
console.log(`${skillName} 사용! (MP: ${props.mp})`);
return true;
}
return false;
}
}
const player = new Player("마법사");
console.log(player.status);
player.useSkill("파이어볼");
|
꿀팁! 🍯
- 심볼 사용 시기
1
2
3
4
5
6
7
8
9
10
11
12
13
| // 1. 유니크한 프로퍼티 키가 필요할 때
const uniqueKey = Symbol("설명");
// 2. 프라이빗 데이터를 만들 때
const _private = Symbol("private");
obj[_private] = "비밀 데이터";
// 3. 내장 동작을 커스터마이징할 때
class MyArray {
[Symbol.iterator]() {
// 커스텀 반복 동작
}
}
|
이제 심볼은 마스터! 😎
유니크한 값이 필요하거나 프라이빗한 데이터를 다룰 때 유용하게 사용할 수 있어!