# Symbol type

## Symbols

symbol 代表唯一的值。

```javascript
// id is a new symbol
let id = Symbol();

// id is a symbol with the description "id" for debug purpose
let id = Symbol("id");

// same description but different value
let id1 = Symbol("id");
let id2 = Symbol("id");

alert(id1 == id2); // false
```

### Symbols don’t auto-convert to a string

&#x20;​JavaScript 大多數的值可以自動轉換成 string 但 symbol 無法自動轉換。

```javascript
let id = Symbol("id");
alert(id); // TypeError: Cannot convert a Symbol value to a string

// convert to string
let id = Symbol("id");
alert(id.toString()); // Symbol(id), now it works

// only get description
let id = Symbol("id");
alert(id.description); // id
```

## “Hidden” properties

symbol 可以為物件創造隱藏的屬性，程式碼的其他部份不容易取得或改寫。

```javascript
let user = { name: "John" };
let id = Symbol("id");

user[id] = "ID Value";
alert( user[id] ); // we can access the data using the symbol as the key

// useing string would be a conflict 
let user = { name: "John" };

// our script uses "id" property
user.id = "ID Value";

// ...if later another script the uses "id" for its purposes...

user.id = "Their id value"
// boom! overwritten! it did not mean to harm the colleague, but did it!
```

### Symbols in a literal

使用 symbol 作為 key 值，要加上 \[ ] 因為它是一個變數。&#x20;

```javascript
let id = Symbol("id");

let user = {
  name: "John",
  [id]: 123 // not just "id: 123"
};
```

### Symbols are skipped by for…in

symbol 不算在物件迴圈內 `for ( in )`。

```javascript
let id = Symbol("id");
let user = {
  name: "John",
  age: 30,
  [id]: 123
};

for (let key in user) alert(key); // name, age (no symbols)

// the direct access by the symbol works
alert( "Direct: " + user[id] );

// Object.assign() 會複製 symbol
let id = Symbol("id");
let user = {
  [id]: 123
};

let clone = Object.assign({}, user);

alert( clone[id] ); // 123

// other type of key convert to string
let obj = {
  0: "test" // same as "0": "test"
};

// both alerts access the same property (the number 0 is converted to string "0")
alert( obj["0"] ); // test
alert( obj[0] ); // test (same property)
```

## Global symbols

symbol 通常是唯一的值，但如果想要同樣的 symbol 可以用 `Symbol.for(key)` 設定全域 symbol registry。

```javascript
// read from the global registry
let id = Symbol.for("id"); // if the symbol did not exist, it is created

// read it again
let idAgain = Symbol.for("id");

// the same symbol
alert( id === idAgain ); // true
```

### Symbol.keyFor

`Symbol.keyFor(sym)` 返回全域 symbol 的 key名稱。

```javascript
let sym = Symbol.for("name");
let sym2 = Symbol.for("id");

// get name from symbol
alert( Symbol.keyFor(sym) ); // name
alert( Symbol.keyFor(sym2) ); // id

// 只能使用在全域的 symbol
alert( Symbol.keyFor(Symbol.for("name")) ); // name, global symbol
alert( Symbol.keyFor(Symbol("name2")) ); // undefined, the argument isn't a global symbol
```

## System symbols

* `Symbol.hasInstance`
* `Symbol.isConcatSpreadable`
* `Symbol.iterator`
* `Symbol.toPrimitive`
* …and so on.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://mistborn.gitbook.io/til-coding/javascript/symbol-type.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
