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

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...inObject.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 は、numberstring と同じ「プリミティブ型」の 1つで、
「絶対にかぶらない一意な値」 を表す。

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

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

for...inObject.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をコピーしました