Javascriptのシンボル

シンボルを理解する:オブジェクトプロパティの一意のデータ型

JavaScriptでは、シンボルはオブジェクトプロパティの識別子を作成するために使用できる一意のデータ型です。記号は文字列や数値とは異なり、これらのデータ型に変換することはできません。これが、識別子の作成に理想的な理由です。

Javascriptでの記号の使用

シンボルを作成するときに、オプションで説明を付けることができます。これはデバッグに役立ちますが、必須ではありません。

シンボルの作成は簡単です。

const mySymbol = Symbol();

説明付きのシンボルを作成することもできます。

const mySymbol = Symbol("my description");

同じ説明で複数のシンボルを作成すると、それらは異なる値になります。

const sym1 = Symbol("foo");
const sym2 = Symbol("foo");

// false
console.log(sym1 === sym2);

シンボルのユニークな点

シンボルは、オブジェクトプロパティの識別子としてよく使用されます。これは、記号が一意であることが保証されており、文字列に変換されないためです。

const obj = {};
obj[mySymbol] = "bar";

// "bar"
console.log(obj[mySymbol]);

シンボルはオブジェクトプロパティのキーとして使用できますが、JSONのプロパティ名(キー)として使用することはできません。

const sym = Symbol("foo");
const obj = { [sym]: "bar" };

// {}
console.log(JSON.stringify(obj));

シンボルは列挙できないため、オブジェクトでfor-inループを使用してもシンボルは表示されません。

const obj = {};
obj[Symbol("a")] = "a";
obj[Symbol("b")] = "b";

for (var key in obj) {
  // undefined
  console.log(key);
}

Object.getOwnPropertySymbolsを使用して、オブジェクト上のすべてのシンボルの配列を取得できます。

const obj = {};
obj[Symbol("a")] = "a";
obj[Symbol("b")] = "b";

const symbols = Object.getOwnPropertySymbols(obj);

// [Symbol(a), Symbol(b)]
console.log(symbols);

シンボルをイテレータとして使用する

よく知られているSymbol.iteratorを使用して、イテレーターとして使用できるシンボルを取得できます。

const arr = [1, 2, 3];
const it = arr[Symbol.iterator]();

// { value: 1, done: false }
console.log(it.next());

// { value: 2, done: false }
console.log(it.next());

// { value: 3, done: false }
console.log(it.next()); 

// { value: undefined, done: true }
console.log(it.next());

より現実的な例

独自のシンボルを作成することはできますが、それらが一意であることを保証する方法はありません。一意のシンボルが必要な場合は、Symbol()を使用する必要があります。

人を表すオブジェクトがあるとします。個人の生年月日を格納するプロパティをこのオブジェクトに追加したいが、このプロパティを列挙可能にしたくない。これは、シンボルを使用して行うことができます。

const person = {
  name: "John Doe"
};
const birthYear = Symbol("birth year");
person[birthYear] = "1955";

for (var key in person) {
  // name
  console.log(key); 
}

// 1955
console.log(person[birthYear]);