(-> % read write unlearn)

My writings on this area are my own delusion

Javascript の Symbol

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 にしている。もともとの思想と衝突している気もするが、これができてしまうこと自体と利用用途は面白い。

Lambda Island

参考