まず「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"
JavaScriptnumber, 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 キーは出ない)
JavaScriptObject.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 の本質はかなり理解できています。
