シンボル(Symbol)って何?


symbolicなsymbol。

tl;dr

  • symbol はES6で導入された新しいプリミティブ。
  • symbol( [description] ) で作成。
  • 作成するたびにまったく新しいSymbolを返す。

シンボルとは?

symbolは、ユニーク1 で不変なデータ型で、オブジェクトのプロパティ識別子として使われたりします。symbolオブジェクトは、Symbolプリミティブデータ型をラップした暗黙的なオブジェクトです。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol

一度作成した symbol はそれ自身とのみ等しい。
ということは、
まったく同じ symbol は二度と作ることはできない。

作成方法

const sym1 = Symbol();

const sym2 = Symbol("デバッグ用の説明。これは、Symbol自体には関係がない。");

new 演算子を用いた構文はエラーを投げます。

new Symbol(); // TypeError
new Symbol("イエーイ"); // TypeError

下のコードでは、すべて false が返されます。

Symbol() === Symbol(); // false
Symbol("abc") === Symbol("abc"); // false 

オブジェクトのキーとして利用する

let obj = {};
const sym = Symbol("obj のキー");
obj[sym] = "xyz";

console.log(obj[sym]); // "xyz"

symbol はオブジェクトのキーとして利用することができる。
これを利用すれば、

  • キーが被ることがない。
  • ライブラリ・フレームワークなどとキーでの衝突を防げる (そのような状況になったことはないが)。
  • キーを文字列で指定した場合に比べて、改変などされるリスクが減る (決してなくなるわけではない 2)。

Symbol( key ) の利用


Symbol() と対照的に、Symbol.for() 関数はグローバルシンボルレジストリリスト内で利用可能なシンボルを生成します。Symbol.for() は必ずしもすべての呼び出しで新しいシンボルを生成するわけでなく、引数で与えられた key をもつシンボルがレジストリ内にすでに存在しているかどうか最初に調べます。存在している場合は、そのシンボルが返されます。引数で与えられたキーをもつシンボルが見つからない場合、 Symbol.for() は新しいグローバルシンボルを生成します。

https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/for#%E8%AA%AC%E6%98%8E

つまり、

  • 同じ key を指定すれば、 同じ Symbol を生成できるってこと (なはず。。。)
let obj = {};
const sym1 = Symbol();
const sym2 = Symbol("debug");
const sym3 = Symbol.for("key");

obj[sym1] = "lorem";
obj[sym2] = "ipsum";
obj[sym3] = "dolor";

// 下記は undefined を返す
console.log(obj[Symbol()]);
console.log(obj[Symbol("debug")]);
console.log(obj[Symbol.for("debug")]);

// 下記は セットした値を返す
console.log(obj[Symbol.for("key")]); // "dolor"

Symbol.keyFor( sym ) の利用

引数で与えられたシンボルに対してグローバルシンボルレジストリから共有シンボルキーを取得します。
https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Symbol/keyFor

つまり、

  • Symbol.for( key ) で作成した symbol から また key を探せる

という解釈????

const sym1 = Symbol();
const sym2 = Symbol("debug");
const sym3 = Symbol.for("key");

console.log(Symbol.keyFor(sym1)); // undefined
console.log(Symbol.keyFor(sym2)); // undefined
console.log(Symbol.keyFor(sym3)); // "key"

結論

  • だいたいはつかめた。
  • 使うタイミングが私にはまだないかも。(あったら教えてください)
  • まだでも、それ自体がsymbolicではっきりとわからない。

  1. 唯一の, たった一つの, ほかにない, 一意の という意味。決して、変わったとかいう意味ではない。 

  2. Object.getOwnPropertySymbols( obj ) で指定されたシンボルの配列を取得できるため。