TypeScript Handbook を読む (11.  Symbols)

[TypeScript Handbook](https://www.typescriptlang.org/docs/handbook/basic-types.html) を読み進めていく第十一回目。

1. [Basic Types](http://qiita.com/murank/items/9c1f633545842c953947)
1. [Variable Declarations](http://qiita.com/murank/items/913f1c1e4e725047436c)
1. [Interfaces](http://qiita.com/murank/items/553276c3dc2eec9bfe47)
1. [Classes](http://qiita.com/murank/items/7e8f15225bc8259e9bf3)
1. [Functions](http://qiita.com/murank/items/e310ce68ed5a0058d42d)
1. [Generics](http://qiita.com/murank/items/144b686d34fd433a97a3)
1. [Enums](http://qiita.com/murank/items/cc487562b21bae3728ba)
1. [Type Inference](http://qiita.com/murank/items/e67ad7426020321228e9)
1. [Type Compatibility](http://qiita.com/murank/items/e06efb0615294a6826e3)
1. [Advanced Types](http://qiita.com/murank/items/bc1776efbecbd2120d94)
1. Symbols (今ココ)
1. [Iterators and Generators](http://qiita.com/murank/items/7ceec53dde886f31a682)
1. [Modules](http://qiita.com/murank/items/0fc4e059be8ea5e1c274)
1. [Namespaces](http://qiita.com/murank/items/0dfad4a0bb91aaa6c97b)
1. [Namespaces and Modules](http://qiita.com/murank/items/0be1978a3515fc76e7ba)
1. [Module Resolution](http://qiita.com/murank/items/5f11466474d49498bbd5)
1. [Declaration Merging](http://qiita.com/murank/items/ec90ba04edab1ea3718e)
1. [JSX](http://qiita.com/murank/items/90164aa9a3bed3c49a80)
1. [Decorators](https://qiita.com/murank/items/580e34883e0832ca7aed)
1. [Mixins](https://qiita.com/murank/items/e77ad8359ed1fd82822d)
1. [Triple-Slash Directives](https://qiita.com/murank/items/faff57883338ebdeda12)
1. [Type Checking JavaScript Files](https://qiita.com/murank/items/588eaddfe8af59914658)


# Symbols
[原文](https://www.typescriptlang.org/docs/handbook/symbols.html)


## Introduction
ECMAScript 2015 からプリミティブ型に `symbol` が追加されました。
`symbol` 型の値は `Symbol` コンストラクタを呼ぶことで作成します。

```ts:TypeScript
let sym1 = Symbol();

let sym2 = Symbol("key"); // 文字列キーは任意
```
```js:JavaScrypt
var sym1 = Symbol();

var sym2 = Symbol("key"); // 文字列キーは任意
```
>別に TypeScript が他の型に変換するわけではないのね

シンボルは変更不可で、かつ、一意です。

```ts:TypeScript
let sym2 = Symbol("key");
let sym3 = Symbol("key");

sym2 === sym3; // false、シンボルは常に一意
```

シンボルは文字列のようにオブジェクトのプロパティとして使用できます。

```ts:TypeScript
let sym = Symbol();

let obj = {
    [sym]: "value"
};

console.log(obj[sym]); // "value"
```
>オブジェクトのプロパティにする場合は `[]` で囲むのかな?

また、計算されたプロパティとして使用することも可能です。

```ts:TypeScript
const getClassNameSymbol = Symbol();

class C {
    [getClassNameSymbol](){
       return "C";
    }
}

let c = new C();
let className = c[getClassNameSymbol](); // "C"
```
>`c[getClassNameSymbol]` で `function` が返るから、それを呼び出しているだけ


## Well-known Symbols
TypeScript の内部的な振る舞いを制御するためのシンボルがいくつか用意されています。
>いろいろ値を変更して振る舞いをカスタマイズできるようだけど、正直なところ、これらの値を変更することはまずないだろう

### `Symbol.hasInstance`
コンストラクタオブジェクトのインスタンスとしてオブジェクトを認識するかどうかを判定する関数。
`instanceof` 演算子で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/hasInstance)

### `Symbol.isConcatSpreadable`
`Array.prototype.concat` を呼んだ時に、オブジェクトを配列として展開するかどうかを示す真偽値。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/isConcatSpreadable)

### `Symbol.iterator`
オブジェクトのデフォルトイテレータを返却する関数。
`for ... of` で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/iterator)

### `Symbol.match`
文字列に対し、正規表現でのマッチングを行う正規表現関数。
`String.prototype.match` で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/match)

### `Symbol.replace`
部分文字列の置換を行う正規表現関数。
`String.prototype.replace` で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/replace)

### `Symbol.search`
正規表現に一致する部分のインデックスを返却する正規表現関数。
`String.prototype.search` で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/search)

### `Symbol.species`
派生クラスを作成するためのコンストラクタ関数を指定する関数。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/species)

### `Symbol.split`
正規表現に一致する部分で文字列を分割する正規表現関数。
`String.prototype.split` で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/split)

### `Symbol.toPrimitive`
オブジェクトを対応するプリミティブ型に変換する関数。
`ToPrimitive` 演算子で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toPrimitive)

### `Symbol.toStringTag`
オブジェクトのデフォルトの文字列表現を作成する際に使用される文字列。
`Object.prototype.toString` で使用されます。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/toStringTag)

### `Symbol.unscopables`
`with` 構文を使用した時にバインド対象外とするプロパティを指定するオブジェクト。
>[MDN](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/unscopables)