JavaScript | 基礎構文:データ型 – Symbol

JavaScript JavaScript
スポンサーリンク
スポンサーリンク

まず「Symbol(シンボル)」を一言でいうと

Symbol は、
「絶対にかぶらない“特別なラベル”を作るためのデータ型」 です。

同じ説明を付けて作っても、
毎回 必ず違う値 になります。

const a = Symbol("id");
const b = Symbol("id");

console.log(a === b); // false(説明が同じでも中身は別物)
JavaScript

見た目は似ていても、内部的には完全に別人。
だから「絶対に他と衝突しないキー」が欲しいときに使います 。

ここが重要です。
Symbol は「一意な値(ユニークな値)」を保証するための型。
特に「オブジェクトのプロパティキーとして使うことで、他のコードと衝突しない“隠しプロパティ”を作る」のが主な用途です。


Symbol の基本:どう作る?何に使う?

Symbol の作り方と「説明(description)」

Symbol を作るには Symbol() を呼びます。

const sym1 = Symbol();
const sym2 = Symbol("userId"); // 説明つき
const sym3 = Symbol("userId"); // 説明が同じでも別物

console.log(sym2 === sym3); // false
JavaScript

カッコの中の "userId" は「説明(description)」であって、
値そのものではありません。

説明は主に「デバッグするときに見分けやすくするため」のラベルです。
説明が同じでも、Symbol は毎回必ず違う値になります。

typeof の結果と「プリミティブ型」

typeof で調べると symbol と出ます。

const s = Symbol("test");
console.log(typeof s); // "symbol"
JavaScript

number, string, boolean などと同じ「プリミティブ型」の一種です。


なぜ Symbol が必要なのか:一意なプロパティキーという発想

普通のプロパティキーは文字列なので、かぶり得る

オブジェクトのプロパティキーは、
通常は文字列(または暗黙に文字列化されるもの)です。

const user = {
  id: 1,
  name: "Taro",
};

user["id"];   // 1
user["name"]; // "Taro"
JavaScript

別のコードが同じオブジェクトに "id" というキーで何か追加したら、
衝突して上書きしてしまう可能性 があります。

Symbol をキーにすると、絶対にかぶらない

Symbol をプロパティキーにすると、そのキーは完全に一意です。

const user = { name: "Taro" };

const ID = Symbol("id");

user[ID] = 123;

console.log(user.name); // "Taro"
console.log(user[ID]);  // 123
JavaScript

ここで重要なのは、

文字列 "id" でアクセスしても、この値は見えない
ID という Symbol を知っている人だけが、この値を取り出せる

という点です。

console.log(user.id);      // undefined
console.log(user["id"]);   // undefined
console.log(user[ID]);     // 123(Symbol を使ったときだけ読める)
JavaScript

他人のコードが "id" という文字列キーで何かしても、
あなたの Symbol("id") キーとは 絶対に衝突しません。

ここが重要です。
「オブジェクトに“他から見えにくい・かぶらない追加情報”を埋め込みたい」
ときに Symbol をキーとして使うと、安全に拡張できます。
いわば“半分隠れたプロパティ”を作るための道具です。


Symbol の代表的な使いどころ(イメージ中心)

ライブラリ・共通オブジェクトを壊さないための「秘密の鍵」

たとえば、共通オブジェクトに自分用の情報を足したいとき。

const CONFIG = {}; // どこかの共通設定オブジェクトだとする

const MY_KEY = Symbol("my-config");

CONFIG[MY_KEY] = { theme: "dark" };
JavaScript

他の人が同じオブジェクトに、

CONFIG["theme"] = "light";
CONFIG["my-config"] = {...};
JavaScript

などと書いても、あなたの CONFIG[MY_KEY] とは一切衝突しません。
Symbol の最大の価値は 「他人とプロパティ名がかぶらない安心感」 です。

「列挙されない」ので、表に出にくい

for...in や Object.keys() などでプロパティを列挙しても、
Symbol キーのプロパティは基本的に出てきません。

const ID = Symbol("id");

const user = {
  name: "Taro",
  [ID]: 123,
};

console.log(Object.keys(user)); // ["name"](Symbol キーは出ない)
JavaScript

Object.getOwnPropertySymbols(user) を使えば、
Symbol キーだけを取り出せますが、
通常の操作では目立ちません。

ここが重要です。
Symbol キーのプロパティは「普通には見えない」「名前もかぶらない」ので、
ライブラリや共通オブジェクトの“裏側の情報”を安全に保存するのに向いています。


グローバル Symbol レジストリと Symbol.for(少しだけ)

同じキーで「共有したい Symbol」を作る方法

普通の Symbol("key") は、
同じ "key" を渡しても毎回別物です。

Symbol("foo") === Symbol("foo"); // false
JavaScript

一方で、Symbol.for("foo") を使うと、
「グローバルレジストリ」から同じ Symbol を取り出す/作る ことができます。

const s1 = Symbol.for("shared");
const s2 = Symbol.for("shared");

console.log(s1 === s2); // true(まったく同じ Symbol)
JavaScript
  • まだ "shared" 用の Symbol がなければ新しく作る
  • すでにあれば、その同じ Symbol を返す

という動きをします。

「アプリ全体で共通の Symbol を使いたい」ときには、
Symbol.for が使われます。


「よくある疑問」にざっくり答えておく

質問1:初心者は Symbol をいきなり使うべき?

正直に言うと、

日常的な初歩コード(if、for、配列、オブジェクト)では、
Symbol はほとんど出番がありません。

ただし、

ライブラリ内部
フレームワーク内部
独自の拡張機構

など、「他のコードと絶対に衝突したくない場所」で
かなり重要な役を担っています。

「存在を知っているかどうか」で、
よそのコードを読むときの理解度が大きく変わるので、
“使いこなす”より“何者かを知っておく”ことのほうが重要 です。

質問2:String のキーじゃダメなの?

「自分で十分にユニークな文字列を考えればいいのでは?」
と思うかもしれません。

確かに小さなコードなら "__mySuperSecretKey__" などで
ほぼ衝突しないようにはできますが、

  • ライブラリ同士が偶然同じ名前を使う
  • 他の人のコードがそのキーに気づかずに上書きする
  • for...in などで列挙されてしまい、意図せず操作される

などのリスクがあります。

Symbol は 言語レベルで一意性と非衝突性を保証してくれる ので、
「本気で衝突を避けたい場面」では、
文字列キーよりはるかに安全です。


初心者としての Symbol の押さえどころ

最後に、最初の段階で本当に押さえておきたいポイントだけを整理します。

Symbol は、number や string と同じ「プリミティブ型」の 1つで、
「絶対にかぶらない一意な値」 を表す。

Symbol("説明") と書くと新しい Symbol を作れるが、
同じ説明を渡しても毎回別物になる。

オブジェクトのプロパティキーとして使うと、
他の文字列キーと絶対に衝突しない「隠れたキー」を作れる。

for...in や Object.keys() には出てこないので、
通常の操作からは見えにくい“裏のプロパティ”を持たせるのに向いている。

Symbol.for("key") を使うと、「同じ文字列キーに対して同じ Symbol」を
グローバルに共有できる。

ここが重要です。
Symbol は「今すぐ毎日使うもの」ではないけれど、
“絶対に衝突しないラベル”“オブジェクトの裏側に情報を持たせる仕組み”として
JavaScript の設計やライブラリの内部を支えている存在です。
「ユニークなプロパティキーが必要になったら Symbol」という引き出しを
頭のどこかに置いておいてください。

もし練習するなら、次のようなコードを書いてみると感覚がつかみやすいです。

const SECRET = Symbol("secret");

const user = { name: "Taro" };
user[SECRET] = "hidden value";

console.log(user);            // { name: 'Taro', [Symbol(secret)]: 'hidden value' } ※コンソール表示による
console.log(user[SECRET]);    // "hidden value"
console.log(Object.keys(user)); // ["name"]
JavaScript

「普通のキーでは見えないけれど、Symbol を知っている自分だけがアクセスできる情報」
という感覚が掴めたら、Symbol の本質はかなり理解できています。

タイトルとURLをコピーしました