JavaScript/Symbol
Symbolは、ECMAScript 2015(ECMASCript 6th Edition: ES6)で導入された新しいデータ型であり、プリミティブ型の一種です[1]。 Symbolは、ユニークな識別子を生成するために使用されます。 従来のJavaScriptの文字列や数値とは異なり、Symbolは他のどの値とも異なることが保証されています。 Symbolは、オブジェクトのプロパティ名として使用されることが多く、ES6で導入された新しい機能であるプロキシや反復子などでも使用されています。 このチュートリアルでは、Symbolの基本的な使い方、作成方法、プロパティ、メソッド、および実用的な例について解説します。
Symbolの基本的な使い方
編集Symbolは、プリミティブデータ型の一つであり、一意の識別子を作成するために使用されます。Symbolは、文字列とは異なり、値が一意であるため、異なる場所で同じSymbolを使用することができます。Symbolは、通常オブジェクトのプロパティ名として使用され、他のプロパティ名と混同されることがないようにするために使用されます。
作成方法
編集Symbolを作成するには、グローバルなSymbol()関数を呼び出します。引数を渡すことができますが、引数は説明的な目的でのみ使用され、Symbolの一意性には影響を与えません。
const sym1 = Symbol(); const sym2 = Symbol('description');
プロパティとメソッド
編集静的プロパティ
編集名称 | 解説 |
---|---|
Symbol.asyncDispose
|
非同期リソースのクリーンアップ処理を定義するために使用されます。特定のオブジェクトが非同期処理終了時にリソースを解放する際に役立ちます。 |
Symbol.asyncIterator
|
非同期イテレーターを定義するために使用されます。このシンボルを持つメソッドを実装することで、オブジェクトを for await...of ループで反復処理できるようになります。
|
Symbol.dispose
|
リソースの同期的なクリーンアップ処理を定義するために使用されます。このシンボルを利用して、特定のオブジェクトのスコープを抜けたときにリソースを解放できます。 |
Symbol.hasInstance
|
instanceof 演算子のカスタマイズを可能にします。このシンボルを持つメソッドを実装することで、オブジェクトが特定のクラスやコンストラクタと互換性があるかどうかを定義できます。
|
Symbol.isConcatSpreadable
|
Array.prototype.concat() メソッドを使用した際に、オブジェクトを展開するかどうかを制御するために使用されます。true に設定すると、配列のように展開されます。
|
Symbol.iterator
|
オブジェクトのデフォルトのイテレーター関数を定義するために使用されます。このシンボルを持つメソッドを実装することで、オブジェクトを for...of ループで反復処理できるようになります。
|
Symbol.length
|
このシンボルはまだ正式に仕様に含まれていませんが、将来的に特定のオブジェクトの長さ情報を扱うために使用される可能性があります。 |
Symbol.match
|
String.prototype.match() メソッドが呼び出された際に、オブジェクトのカスタム動作を定義するために使用されます。
|
Symbol.matchAll
|
String.prototype.matchAll() メソッドが呼び出された際に、オブジェクトのカスタム動作を定義するために使用されます。すべての一致を反復可能なオブジェクトとして返します。
|
Symbol.name
|
Symbolオブジェクトの名前。 'Symbol' |
Symbol.prototype
|
すべてのシンボルが継承するプロトタイプオブジェクトを表します。シンボルに関連するメソッドが定義されています。 |
Symbol.replace
|
String.prototype.replace() メソッドが呼び出された際に、オブジェクトのカスタム動作を定義するために使用されます。
|
Symbol.search
|
String.prototype.search() メソッドが呼び出された際に、オブジェクトのカスタム動作を定義するために使用されます。
|
Symbol.species
|
派生オブジェクトを作成する際に、その元となるオブジェクトのコンストラクタを参照するために使用されます。例えば、配列メソッドが新しい配列を返す際に使用されます。 |
Symbol.split
|
String.prototype.split() メソッドが呼び出された際に、オブジェクトのカスタム動作を定義するために使用されます。
|
Symbol.toPrimitive
|
オブジェクトをプリミティブ値に変換する際のカスタム動作を定義するために使用されます。このシンボルを持つメソッドを実装することで、数値や文字列などの変換方法を制御できます。 |
Symbol.toStringTag
|
オブジェクトの文字列表現に使用されるシンボルです。このシンボルをカスタマイズすることで、Object.prototype.toString.call(obj) の出力を制御できます。
|
Symbol.unscopables
|
with 文のスコープ内で無視されるプロパティを定義するために使用されます。このシンボルを設定することで、with 文の挙動をカスタマイズできます。
|
- Well-Known Symbols
- Well-Known Symbolsは、JavaScriptにおいて標準的に定義されたシンボルで、特定の動作をするために使用されます。
静的アクセサ
編集静的メソッド
編集名称 | 解説 |
---|---|
Symbol.for()
|
グローバルシンボルレジストリから、指定されたキーを持つシンボルを検索します。存在する場合はそのシンボルを返し、存在しない場合は新しいシンボルを作成して返します。 |
Symbol.keyFor()
|
グローバルシンボルレジストリで登録されたシンボルのキーを返します。グローバルシンボルレジストリで登録されていないシンボルに対して使用された場合、undefined を返します。
|
実用的な例
編集Symbolは、オブジェクトのプロパティ名として使用されることが多く、以下のような例があります。
const MY_KEY = Symbol(); const obj = {}; obj[MY_KEY] = 123; console.log(obj[MY_KEY]); // 123
また、グローバルシンボルレジストリを使用して、アプリケーション全体で一意のシンボルを共有することができます。例えば、以下のようにして、シンボルを共有することができます。
- module1.js
const MY_KEY = Symbol.for('my key');
- module2.js
const MY_KEY = Symbol.for('my key'); console.log(MY_KEY === module1.MY_KEY); // true
インスタンスプロパティ
編集名称 | 解説 |
---|---|
Symbol.prototype [ Symbol.toStringTag ]
|
Object.prototype.toString() メソッドで使用される、オブジェクトの既定の文字列表現を指定するシンボルです。Symbol オブジェクトの場合、"Symbol" という文字列を返します。
|
- 詳細
Symbol.toStringTag
は、Object.prototype.toString()
メソッドがオブジェクトの文字列表現を生成する際に使用される特別なシンボルです。- 通常、
Object.prototype.toString()
は、[object Object]
のように、オブジェクトの型を示す文字列を返します。 - しかし、
Symbol.toStringTag
プロパティがオブジェクトに定義されている場合、その値がオブジェクトの型として使用されます。 Symbol.prototype[Symbol.toStringTag]
は、Symbol
オブジェクトの文字列表現を[object Symbol]
にするために使用されます。
- 例
const symbol = Symbol('mySymbol'); console.log(Object.prototype.toString.call(symbol)); // "[object Symbol]"
- 補足
Symbol.toStringTag
は、カスタムオブジェクトの文字列表現をカスタマイズするためにも使用できます。Symbol.toStringTag
は、ECMAScript 2015で導入されました。
インスタンスアクセサ
編集名称 | 解説 |
---|---|
get Symbol.prototype.description
|
シンボルの説明文字列を返すアクセッサプロパティです。シンボルに説明がない場合は undefined を返します。
|
インスタンスメソッド
編集名称 | 解説 |
---|---|
Symbol.constructor()
|
Symbol オブジェクトのインスタンスを生成した関数を返します。
|
Symbol.toString()
|
シンボルの文字列表現を返します。 |
Symbol.valueOf()
|
シンボルオブジェクトのプリミティブ値を返します。 |
Symbol.prototype [ Symbol.toPrimitive ] ()
|
オブジェクトをプリミティブ値に変換する際のカスタム動作を定義するために使用されます。このシンボルを持つメソッドを実装することで、数値や文字列などの変換方法を制御できます。 |
附録
編集チートシート
編集以下は、JavaScriptのSymbolに関するチートシートです。
// Symbolの基本的な使い方 const mySymbol = Symbol('mySymbol'); // 作成方法 const symbol1 = Symbol(); const symbol2 = Symbol('symbol2'); // プロパティ console.log(Symbol.iterator); // Symbol(Symbol.iterator) // メソッド const symbol3 = Symbol.for('symbol3'); console.log(Symbol.keyFor(symbol3)); // symbol3 // 実用的な例 const myObj = {}; const mySymbol1 = Symbol('mySymbol1'); const mySymbol2 = Symbol('mySymbol2'); myObj[mySymbol1] = 'value1'; myObj[mySymbol2] = 'value2'; console.log(myObj[mySymbol1]); // value1 console.log(myObj[mySymbol2]); // value2
上記のコードでは、以下の内容を含んでいます。
- 基本的なSymbolの使い方
- Symbolの作成方法に関する例
- Symbolオブジェクトのプロパティの例(Symbol.iterator)
- Symbolオブジェクトのメソッドの例(Symbol.for、Symbol.keyFor)
- 実用的な例として、Symbolを使ってオブジェクトにプロパティを追加する例
このチートシートは、Symbolの基本的な使い方やプロパティ、メソッド、実用的な例を網羅しています。 これらの情報を参考に、Symbolを使った開発をスムーズに進めていくことができるでしょう。
用語集
編集- Symbol: ES2015で導入されたプリミティブ型の一つで、一意の識別子を作成するために使用されます。
- Symbol.for(key): グローバルなシンボルレジストリを介して、指定されたキーで登録された既存のシンボルを返します。存在しない場合は、新しいシンボルを作成します。
- Symbol.keyFor(sym): グローバルなシンボルレジストリから、指定されたシンボルに関連付けられたキーを取得します。キーが見つからない場合はundefinedを返します。
- Symbol.iterator: オブジェクトがfor...ofループで反復可能であることを示すシンボルです。
- Well-Known Symbols: 既存のシンボルのうち、特定の目的で予約されているものを示す用語です。例えば、Symbol.iteratorはWell-Known Symbolsの一つです。
- Symbol.species: インスタンスを作成するためのファクトリーメソッドを持つコンストラクタ関数において、生成されるオブジェクトの種類を表すシンボルです。
- Symbol.hasInstance: オブジェクトが特定のコンストラクタ関数のインスタンスであるかどうかを判定するために使用されるシンボルです。
- Symbol.toStringTag: オブジェクトのデフォルトの文字列化時に使用されるタグ名を表すシンボルです。
- Symbol.match: 正規表現のマッチングを行うためのシンボルです。
- Symbol.toPrimitive: オブジェクトをプリミティブ値に変換するためのシンボルです。
- Symbol.isConcatSpreadable: 配列をconcat()メソッドで展開するかどうかを示すシンボルです。
- Symbol.unscopables: with文によってスコープされないプロパティ名の集合を表すシンボルです。
- Symbol.asyncIterator: オブジェクトがfor-await-ofループで反復可能であることを示すシンボルです。