タタッと!ドラゴンさん🐉

タタッ!と書いてく記事まとめ

【TypeScript🚀】Symbolっていつ使うの?

🐉 グォォォオオ! Hello,World!! ドラゴンだ!

🐉ちなみにポケモン種族値は80 - 100 -80 -80 - 80 - 100です。だーれだ!?

🐉 ...

🐉 ...(フライゴンです。ガブリアスは天敵)

🐉今回は TypeScriptで頻度少なくてあまり馴染めないなーって部分の話です!

🐉 ちょこちょこ見てああ!そうだったね!ってなれば嬉しいです。

Symbolの解説と使うシーンっていつ?

TypeScriptを学んでいると、symbolというデータ型が時折紹介されています。 ですが、結構JavaScriptの内容だから〜とか、あんまり使わないから〜と書いてあり省略されがちでした。(少なくとも私の所持するTS本の何点かはそうでした。) この記事では、symbol型の基本的な理解から、そのメリット・デメリット、実際にどのような場面で使用するのかまで、具体的な例を交えて整理します。

Symbolの紹介 まずは簡単な振り返り

symbol型は、JavaScriptにおけるプリミティブ型の一つで、常に一意な値を生成するために使用されます。symbolは、オブジェクトのプロパティキーとして利用されることが多く、他のキーとの衝突を避けるために役立ちます。

基本的な例

const s1: symbol = Symbol("foo");
const s2: symbol = Symbol("foo");

console.log(s1 === s1); // true
console.log(s1 === s2); // false

上記の例では、s1s2は同じ説明文字列 "foo" を持っていますが、異なるsymbolとして扱われるため、s1 === s2falseとなります。

メリット・デメリット

メリット

  1. 一意性の確保
    symbolは常に一意な値を生成するため、オブジェクトのプロパティキーとして使用する際に、他のプロパティと衝突するリスクを避けられます。

  2. プライベートプロパティの実現
    symbolを使用することで、意図的にアクセスを制限したいプロパティを作成できます。これは、ライブラリやフレームワークの内部実装を隠蔽するのに有用です。

デメリット

シリアライズの難しさ
symbol型はJSON.stringify()に渡すとundefinedが返されるため、シリアライズが必要な場面では不向きです。

使うシーンは?

symbolは特定の状況で非常に有用ですが、日常的なアプリケーション開発では頻繁に使用されるわけではありません。以下に具体的な使用例を紹介します。

1. オブジェクトのユニークなプロパティキーとして

他のプロパティと衝突することなく、オブジェクトに新しいプロパティを追加したい場合にsymbolを使用します。

const UNIQUE_KEY = Symbol("uniqueKey");

const obj = {
  [UNIQUE_KEY]: "This is a unique value",
  name: "Alice",
};

console.log(obj[UNIQUE_KEY]); // "This is a unique value"

2. プライベートプロパティの実現

外部からアクセスされにくいプロパティを持つオブジェクトを作成する際にsymbolを活用します。

const privateProp = Symbol("privateProp");

class MyClass {
  constructor() {
    this[privateProp] = "Secret Value";
  }

  getSecret() {
    return this[privateProp];
  }
}

const instance = new MyClass();
console.log(instance.getSecret()); // "Secret Value"
console.log(instance[privateProp]); // "Secret Value"(ただし、symbolを知らない限りアクセスは困難)

3. イテレーターやその他の組み込みプロトコルのカスタマイズ

Symbol.iteratorなどの組み込みシンボルを使用して、オブジェクトのカスタムイテレーターを定義できます。

const iterableObject = {
  data: [1, 2, 3],
  [Symbol.iterator]() {
    let index = 0;
    return {
      next: () => ({
        value: this.data[index],
        done: index++ >= this.data.length,
      }),
    };
  },
};

for (const value of iterableObject) {
  console.log(value); // 1, 2, 3
}

まとめ

symbol型は、一意性を保証するために使います。

  • メリット

    • 一意なプロパティキーの生成
    • プライベートプロパティの実現
  • デメリット

  • 使用シーン

    • オブジェクトのユニークなプロパティキーとして
    • プライベートプロパティの実現
    • イテレーターや組み込みプロトコルのカスタマイズ

symbolを効果的に活用することで、コードの安全性や保守性を向上させることができます。ただし、必要な場面でのみ使用し、過度に依存しないよう注意しましょう。

参考資料