symbol はユニークであることが保証された値を動的に生成できる。
JavaScript の環境では Symbol
関数を使って生成される。
Symbol("ほげ") === Symbol("ほげ") //=> false "ほげ" === "ほげ" //=> true
symbol は ECMAScript 2015 (ES6) で導入された。そのため ECMAScript 5 には存在しない。
symbol は Primitive (プリミティブ、Primitive Value, Primitive Data Type とも)である。
- Primitive であるということは、オブジェクトではなくメソッドを持たず、そして不変(immutable)であるということ。
- Javascript では Primitive は symbol
の他に string
, number
, bigint
, boolean
, undefined
, null
があり あわせて7つのみが存在する。
symbol は文字列に自動変換されない
const Sym = Symbol("ほげ"); console.log(Sym); //=> Symbol(ほげ) alert(Sym); //=> Uncaught TypeError: Cannot convert a Symbol value to a string
これは混合しないための「言語ガード」で、これは文字列とシンボルが根本的に異なるため、そして他の型に変換するべきものではないためです。
しかし toString メソッド自体は普通に使える。また、 description
プロパティから作成時の説明文を取り出せる。
const Sym = Symbol("ほげ"); console.log(Sym.toString()); //=> Symbol(ほげ) console.log(Sym.description); //=> ほげ
well-known symbol と呼ばれる定数が存在する。これらは、言語機能が個々のオブジェクトをどのように扱えるかを示すフラグのような役目を果たすようで、プロパティキーとして使用されている。
例えば @@iterator
という名前(この名前は ECMAScript 上の名前) well-known symbol は Symbol.iterator
というかたちで定数として定義されており、次のような意味を持っている。
A method that returns the default Iterator for an object. Called by the semantics of the for-of statement.
オブジェクトのデフォルトの Iterator を返すメソッド。 for-of ステートメントのセマンティクスによって呼び出されます。
console.log(Symbol.iterator.description);
//=> Symbol.iterator
例えば、イテラブルな代表的なオブジェクトである配列が実際にこのプロパティ値を持つことは次のように確認できる。
[1,2,3][Symbol.iterator] //=> ƒ values() { [native code] } // Symbol.iterator はシンボル値なので、当然そのその文字列値でそのプロパティを参照することはできない。 console.log(Symbol.iterator.description); //=> Symbol.iterator [1,2,3]['Symbol.iterator'] //=> undefined
for-of などでイテレーション可能なオブジェクトを定義しようと思ったら、そのオブジェクトに対してこのプロパティの関数を適宜実装すればいい。これは面白そうなので今度やってみたい。
well-known symbol の一覧は仕様書に記載されている。searchable であることを示す Symbol.search
など Javascript の基本的な言語機能や API に対応するシンボルがたくさん見れる。
ECMAScript® 2025 Language Specification
もともと古いこの動画を見ていて React コンポーネント(初期のクラスコンポーネントのみなのかも)が $$typeof
というプロパティキーにシンボル値をもたせることでそれが React Element なのかを判断する、という機構を持っていた話が解説されていたことから調べたが面白かった。ちなみにこの動画記事では ClojureScript 側から Javascript の Symbol を extends-type
することで Printable にしている。もともとの思想と衝突している気もするが、これができてしまうこと自体と利用用途は面白い。
参考