유일성을 보장해준다.
const sym = Symbol();
const sym2 = Symbol();

console.log(sym); // Symbol() 출력
console.log(sym2);  // Symbol() 출력

console.log(sym === sym2);  // 그렇지만 다르다고 나온다. false
console.log(sym == sym2); // false
const id = Symbol('id'); // 설명을 인자로 넘길 수 있다. debugging 할 때 편하다. 이는 Symbol생성에는 아무런 영향을 미치지 않는다.
const id2 = Symbol('id'); // 둘은 다르다.
const id = Symbol('id');
const user = {
    name : 'malza',
    age : 30,
    [id] : 'myid',
}

console.log(user); // {name: "malza", age: 30, Symbol(id): "myid"}
console.log(user[id]); // myid
console.log(id.description); // id. 생성할 때 적어주었던 id 를 넘겨준다.
우리가 이전에 살펴보았던 Object 의 method를 살펴보자.
const id = Symbol('id');
const user = {
    name : 'malza',
    age : 30,
    [id] : 'myid',
}

console.log(Object.keys(user)); // ["name", "age"] 심볼이 무시 되었다.
console.log(Object.values(user)); // ["malza", 30] 심볼이 무시 되었다.
console.log(Object.entries(user));
(2) [Array(2), Array(2)]
0: (2) ["name", "malza"]
1: (2) ["age", 30]
//심볼이 무시 되었다.

for(const a in user) {
    console.log(a);  // name, age 심볼이 무시 되었다.
}
심볼은 이름이 같아도 다르게 취급한다. 근데 가끔 이름이 같다면 같은 객체를 가리켜야 할 때가 있다.
이때 전역 심볼을 사용 할 수 있다.
Symbol.for()

하나의 symbol 만 보장 받을 수 있다.
없으면 만들고, 있으면 가져오기 때문이다.
Symbol 함수는 매번 다른 Symbol 값을 생성하지만, Symbol.for 메소드는 하나를 생성한 뒤 키를 통해 같은 Symbol 을 공유

const id = Symbol.for('id');
const id2 = Symbol.for('id');
console.log(id === id2); // true
console.log(Symbol.keyFor(id2)); // id. 생성할 때 적어주었던 id를 넘겨준다.
심볼을 완벽하게 숨길 수는 없다.
const id = Symbol('id');

const user = {
    name : 'malza',
    age : 30,
    [id] : 'myid',
}

console.log(Object.getOwnPropertySymbols(user)); // [Symbol(id)]
console.log(Reflect.ownKeys(user)); // symbol을 포함한 모든 키를 보여준다. ["name", "age", Symbol(id)]

이런 메소드를 거의 사용하지 않기 때문에 걱정하지말고 유일한 값이 필요하다면 symbol을 사용하면 된다.
이렇게 꽁꽁 숨겨져 있는 아이는 어떻게 사용이 될까?
특정 객체의 원본 데이터를 건들지 않고 속성을 추가 할 수 있다.

// 만들어져 있던 객체
const user = {
    name : 'malza',
    age : 30,
}

// 사용자가 접속하면 보게 될 메세지
for(const info in user){
    console.log(`user ${info} is ${user[info]}`);
}

//user name is malza
//user age is 30

그런데 내가 저 객체에 무언가를 추가 했다.
user.doSomething = function(){};

이런 짓을 해 버리니까 사용자가 접속하면 보게 될 메세지에
user doSomething is function(){} 와 같은 메세지가 떠 버린다.

그렇기에 심볼을 사용해서 사용자게에 보이지 않게 추가한다.

const doSomething = Symbol('doSomething');
user[doSomething] = function(){
    console.log(this.name);
};

메세지가 추가되지 않은 것을 확인 할 수 있다.
user[doSomething](); // malza 가 잘 출력된다.
// 내가 작업 한 것이 사용자에게 영향을 끼치지 않았고, 내가 필요한 함수도 만들었다.