初心者に分かりやすい!JavaScript 入門チートシート

TwitterFacebookHatena

TL;DR

このページでは、Jamstack を使った構築や、Next.js を使う上で必要となる JavaScript の基礎知識をまとめたものを初心者向けにチートシート形式でご紹介します。JavaScript の主要な特性や概念を分かりやすく網羅していますので、JavaScript の学び直しにもご活用できるかと思います。定期的に見返しましょう!

項目 内容
対象者 - JavaScript の基礎を学び直したい方
- Next.js を使った開発を行いたい方
- フロントエンド開発に興味がある方
レベル 初心者向け
中級者の復習にも適しています
学習時間 60 分 ~ 120 分
必要なツール - テキストエディタ (例: Visual Studio Code)
- ブラウザ (例: Google Chrome)

JavaScript について

JavaScript は、Web ブラウザ上で動くプログラムを作るための言語です。そして、その JavaScript の基本的な使い方を理解することが、Web 開発の一端を担う Next.js や TypeScript を用いて開発を行う上で大切です。

let greeting = "Hello, World!";
console.log(greeting);

ここでは、変数 greeting に文字列 "Hello, World!" を格納し、その値を console.log 関数を使ってコンソールに出力しています。これは JavaScript の基本的な文法の一つで、このような基本的な文法を理解し、それを自由に書けるようになることが「JavaScript の基礎」を理解することにつながります。

変数と定数

JavaScript では、値を保持するために「変数」と「定数」を使います。「変数」は値を変更できますが、「定数」は一度設定した値を変更することはできません。

let variable = "I'm a variable"; // 変数の宣言
variable = "I can change"; // 変数の値を変更

const constant = "I'm a constant"; // 定数の宣言
// constant = "I can't change";  // エラー!定数の値は変更できません

const

constキーワードを使うと、値が再代入できない定数を宣言することができます。つまり、一度値が設定されると、その値を変更することはできません。

const myConstant = "constant value";

これは、その値が不変であるべきと明示的に示す場合に非常に役立ちます。例えば、設定値や環境変数などは通常、アプリケーションの実行中に変更されるべきではないので、これらをconstで宣言するのが適切です。

ただし、constで宣言されたオブジェクトや配列のプロパティは変更可能であることに注意が必要です。つまり、constは変数の再代入を防ぐだけで、その内容が不変であることを保証するわけではありません。

const myObject = { key: "value" };

// これはOK - myObject自体の再代入ではなく、そのプロパティを変更しているだけ
myObject.key = "new value";

// これはエラー - myObject自体を再代入しようとしている
myObject = { key: "another value" };

データ型

JavaScript には、文字列、数値、真偽値、オブジェクト、配列など、さまざまなデータ型があります。

let str = "I'm a string"; // 文字列
let num = 123; // 数値
let bool = true; // 真偽値

let obj = {
  // オブジェクト
  name: "Alice",
  age: 20,
};

let arr = [1, 2, 3, 4, 5]; // 配列

Truthy と Falsy

JavaScript では、真偽値の true または false として評価される値があります。通常、値が存在する場合は truthy、存在しないか無効な場合は falsy となります。

let truthyValue = "I exist"; // Truthy
let falsyValue = ""; // Falsy

null と undefined

JavaScript では、null は明示的に値がないことを示し、undefined は値がまだ設定されていないことを示します。

let nullValue = null; // null
let undefinedValue; // undefined

undefined

JavaScript における undefined は、特定の変数がまだ値を持っていないことを示す特殊な値です。たとえば、値を割り当てていない変数を宣言した場合、その変数の初期値は undefined になります。

let myVar;
console.log(myVar); // "undefined"

また、オブジェクトの特定のプロパティが存在しない場合、そのプロパティの値も undefined になります。

const myObj = { a: 1 };
console.log(myObj.b); // "undefined"

さらに、何も返さない関数は undefined を返すとされます。

function doNothing() {}
console.log(doNothing()); // "undefined"

undefined は、変数やプロパティが意図的に空にされている null とは異なり、値がまだ設定されていないことを示すために使用されます。これは JavaScript の重要な概念であり、変数が定義されているかどうかをチェックするためにしばしば使用されます。

算術演算子

JavaScript には、加算(+)、減算(-)、乗算(*)、除算(/)、剰余(%)などの基本的な算術演算子があります。

let a = 10;
let b = 3;

console.log("a + b =", a + b); // a + b = 13
console.log("a - b =", a - b); // a - b = 7
console.log("a * b =", a * b); // a * b = 30
console.log("a / b =", a / b); // a / b = 3.3333333333333335
console.log("a % b =", a % b); // a % b = 1

また、JavaScript には加算代入(+=)、減算代入(-=)、乗算代入(*=)、除算代入(/=)、剰余代入(%=)などの代入演算子もあります。

let a = 10;

a += 5; // a = a + 5
console.log("a += 5:", a); // a += 5: 15

a -= 3; // a = a - 3
console.log("a -= 3:", a); // a -= 3: 12

a *= 2; // a = a * 2
console.log("a *= 2:", a); // a *= 2: 24

a /= 4; // a = a / 4
console.log("a /= 4:", a); // a /= 4: 6

a %= 5; // a = a % 5
console.log("a %= 5:", a); // a %= 5: 1

テンプレートリテラル

JavaScript では、テンプレートリテラルを使用することで、変数や式を含む文字列を簡単に作成できます。これはバックティック(``)で囲むことで実現します。

let name = "John";
console.log(`Hello, ${name}!`); // Hello, John!

デストラクチャリング

デストラクチャリング代入は、配列やオブジェクトからデータを展開し、それを個々の変数に割り当てるためのシンタックスです。

let [first, second] = ["first", "second"];
console.log(first); // first
console.log(second); // second

オブジェクトリテラル拡張

オブジェクトリテラル拡張は、オブジェクトをよりシンプルに記述できるようにする構文です。

let x = 10,
  y = 20;
let obj = { x, y }; // Same as { x: x, y: y }

メソッド

オブジェクトに紐付けられた関数をメソッドと呼びます。オブジェクトのプロパティとして関数を定義することで、その関数をメソッドとして扱うことができます。

let person = {
  name: "Alice",
  greet: function () {
    console.log(`Hello, my name is ${this.name}`);
  },
};

person.greet(); // "Hello, my name is Alice"

プロパティアクセス式

JavaScript のオブジェクトにはプロパティ(属性やメソッド)が存在し、それぞれに値が格納されています。オブジェクトのプロパティにアクセスするための主な方法は二つあります。それはドット . を使った記法(ドット記法)と、角括弧 [] を使った記法(ブラケット記法)です。

ドット記法

ドット記法は最も一般的なプロパティアクセスの方法で、以下のように使用します。

let obj = {
  property: "value",
};

console.log(obj.property); // "value"

ブラケット記法

一方、ブラケット記法はプロパティ名が変数に格納されている場合や、プロパティ名が有効な識別子(例:数字で始まる名前、スペースを含む名前など)でない場合に有用です。

let obj = {
  property: "value",
  "2nd property": "second value",
};

let propertyName = "property";

console.log(obj[propertyName]); // "value"
console.log(obj["2nd property"]); // "second value"

また、ブラケット記法を使用することで、動的にプロパティ名を指定してアクセスすることも可能です。これはプログラムの実行中にプロパティ名が決定される場合などに有用です。

let obj = {
  property: "value",
  anotherProperty: "another value",
};

let propertyName = Math.random() > 0.5 ? "property" : "anotherProperty";

console.log(obj[propertyName]); // "value" or "another value"

ここでは、propertyName の値はプログラムが実行されるたびにランダムに 'property''anotherProperty' のどちらかになり、その結果に基づいて obj の異なるプロパティにアクセスします。

条件分岐

JavaScript では、if 文を使って条件によって処理を分岐することができます。

let num = 10;

if (num > 0) {
  console.log("Positive number");
} else if (num < 0) {
  console.log("Negative number");
} else {
  console.log("Zero");
}

ループ処理

JavaScript では、for 文や while 文を使って繰り返し処理(ループ)を行うことができます。

for (let i = 0; i < 5; i++) {
  console.log(i);
}

let i = 0;
while (i < 5) {
  console.log(i);
  i++;
}

for...in 構文

for...in 構文は、オブジェクトのすべての列挙可能なプロパティに対して反復処理を行います。オブジェクトのキーを反復するために主に使用されます。

let person = {
  name: "Alice",
  age: 20,
  city: "Tokyo",
};

for (let key in person) {
  console.log(`${key}: ${person[key]}`);
}

// 出力:
// name: Alice
// age: 20
// city: Tokyo

for...of 構文

for...of 構文は、反復可能なオブジェクト(配列や文字列など)の各要素に対して反復処理を行います。

let array = [1, 2, 3, 4, 5];

for (let value of array) {
  console.log(value);
}

// 出力:
// 1
// 2
// 3
// 4
// 5

forEach() メソッド

forEach() メソッドは、配列のすべての要素に対して指定した関数を実行します。

let array = [1, 2, 3, 4, 5];

array.forEach((value) => {
  console.log(value);
});

// 出力:
// 1
// 2
// 3
// 4
// 5

map() メソッド

map() メソッドは、配列のすべての要素に対して関数を呼び出し、その結果からなる新しい配列を生成します。

let numbers = [1, 2, 3, 4, 5];
let squares = numbers.map((n) => n * n);

console.log(squares); // [1, 4, 9, 16, 25]

プロトタイプ

JavaScript はプロトタイプベースのオブジェクト指向言語です。これは、オブジェクトが他のオブジェクトから振る舞いを継承することを意味します。

let animal = {
  eats: true,
};

let rabbit = {
  jumps: true,
  __proto__: animal,
};

console.log(rabbit.eats); // true
console.log(rabbit.jumps); // true

この例では、rabbitオブジェクトはanimalオブジェクトをプロトタイプとしています。そのため、rabbitanimalのプロパティを継承します。

スプレッド演算子

スプレッド演算子(...)は、配列やオブジェクトを個々の要素に展開することができます。

let arr1 = [1, 2, 3];
let arr2 = [...arr1, 4, 5];

console.log(arr2); // [1, 2, 3, 4, 5]

この例では、arr1の要素をarr2の中で展開しています。

他に、スプレッド演算子を使うと、配列やオブジェクトをコピーしたり、結合したり、要素を追加したりすることができます。

// 配列のコピー
const array = [1, 2, 3];
const arrayCopy = [...array];
// [1, 2, 3]

// 配列の結合
const array1 = [1, 2, 3];
const array2 = [4, 5, 6];
const array3 = [...array1, ...array2];
// [1, 2, 3, 4, 5, 6]

// 配列の要素の追加
const array = [1, 2, 3];
const arrayCopy = [...array, 4];
// [1, 2, 3, 4]

// オブジェクトのコピー
const obj = { a: 1, b: 2 };
const objCopy = { ...obj };
// { a: 1, b: 2 }

// オブジェクトの結合
const obj1 = { a: 1, b: 2 };
const obj2 = { c: 3, d: 4 };
const obj3 = { ...obj1, ...obj2 };
// { a: 1, b: 2, c: 3, d: 4 }

// オブジェクトの要素の追加
const obj = { a: 1, b: 2 };
const objCopy = { ...obj, c: 3 };
// { a: 1, b: 2, c: 3 }

// オブジェクトの要素の削除
const obj = { a: 1, b: 2 };
const { a, ...objCopy } = obj;
// { b: 2 } で、削除されたプロパティ 'a' の値は一時的な変数 'a' に格納されます。

// オブジェクトの要素の更新
const obj = { a: 1, b: 2 };
const objCopy = { ...obj, b: 3 };
// { a: 1, b: 3 }

関数宣言

JavaScript では、処理をまとめて「関数」を定義することができます。関数は入力(引数)を受け取り、出力(戻り値)を返すことができます。

function greet(name) {
  return "Hello, " + name + "!";
}

console.log(greet("Alice")); // "Hello, Alice!"

関数式

関数式とは、関数を一つの値として扱い、変数に代入する形で表現される関数のことを指します。以下に具体的なコードを示します。

let greet = function (name) {
  console.log(`Hello, ${name}!`);
};

greet("Alice"); // "Hello, Alice!"

上記の例では、無名関数(名前のない関数)を変数greetに代入しています。このgreet変数は、関数として使用することができます。

また、アロー関数を使うと、関数式はより簡潔に書くことができます。

let greet = (name) => {
  console.log(`Hello, ${name}!`);
};

greet("Alice"); // "Hello, Alice!"

この形式の関数は、コールバック関数としてよく使われたり、関数を他の関数に引数として渡す際に使用されます。

クロージャー

クロージャーは、関数とその関数が宣言されたレキシカル環境の組み合わせです。これにより、関数外からはアクセスできないプライベートな変数を作ることができます。

let counter = (() => {
  let privateCounter = 0;
  return () => {
    privateCounter++;
    return privateCounter;
  };
})();

console.log(counter()); // 1
console.log(counter()); // 2

スコープ

スコープとは、変数や関数が参照可能な範囲のことを指します。JavaScript には大きく分けて 3 つのスコープがあります。グローバルスコープ、関数スコープ、ブロックスコープです。

let globalVar = "I'm global"; // これはグローバルスコープ

function showScope() {
  let functionVar = "I'm local"; // これは関数スコープ
  console.log(functionVar);
  console.log(globalVar);
}

showScope();
console.log(globalVar);
console.log(functionVar); // これはエラーになります

このコードでは、globalVarはどこからでも参照することができます。一方、functionVarは関数showScope内からしか参照することができません。このように、スコープは変数の有効範囲を制御します。

アロー関数

アロー関数は、関数表現を短く書くことができる ES6 の新機能です。

let greet = (name) => "Hello, " + name + "!"; // アロー関数

console.log(greet("Alice")); // "Hello, Alice!"

関数式の Async Function

JavaScript では、asyncキーワードを使って非同期関数を定義できます。非同期関数は常に Promise を返します。非同期関数内では、非同期処理の結果を待つためにawaitキーワードを使用することができます。

非同期関数は通常の関数宣言だけでなく、関数式を使っても宣言できます。以下に例を示します。

const myAsyncFunction = async function () {
  const response = await fetch("https://api.example.com/data");
  const data = await response.json();
  console.log(data);
};

この関数myAsyncFunctionは、非同期的にデータをフェッチし、そのデータを JSON 形式にパースし、コンソールに出力します。関数が非同期であるため、データのフェッチとパースが完了するまで他のコードの実行をブロックすることはありません。これにより、非同期のタスクを効率的に管理することができます。

再帰関数

再帰関数は、関数が自分自身を呼び出す関数のことです。

let factorial = (n) => (n === 0 ? 1 : n * factorial(n - 1));

console.log(factorial(5)); // 120

高階関数

高階関数は、他の関数を引数として取ったり、関数を結果として返す関数のことを指します。

let greet = (name) => "Hello, " + name + "!";
let greetTwice = (func, name) => func(name) + " " + func(name);

console.log(greetTwice(greet, "Alice")); // "Hello, Alice! Hello, Alice!"

コールバック関数

コールバック関数は、他の関数に引数として渡され、その関数によって呼び出される関数です。

let numbers = [1, 2, 3, 4, 5];
numbers.forEach((number) => console.log(number)); // コールバック関数

オプションパラメーター

関数のパラメータにデフォルト値を設定することができます。これにより、関数の呼び出し時にそのパラメータが指定されなかった場合でも、デフォルト値が使用されます。

let greet = (name = "Alice") => "Hello, " + name + "!";

console.log(greet()); // "Hello, Alice!"

レストパラメータ(...)

関数のパラメータに ... を使用すると、任意の数の引数を配列として取得できます。

let sum = (...numbers) => numbers.reduce((a, b) => a + b, 0);

console.log(sum(1, 2, 3, 4, 5)); // 15

オブジェクト

JavaScript では、オブジェクトはキーと値のペアを持つコレクションです。

let person = {
  name: "Alice",
  age: 20,
};

console.log(person.name); // "Alice"
console.log(person["age"]); // 20

分割代入

分割代入を使用すると、配列やオブジェクトからプロパティを簡単に抽出できます。

let person = {
  name: "Alice",
  age: 20,
};

let { name, age } = person; // 分割代入

console.log(name); // "Alice"
console.log(age); // 20

演算子

演算子は、一つ以上の値(オペランド)を取り、計算や様々な操作を行います。例えば、+, -, *, / は算術演算子で、==, !=, <, >, <=, >= は比較演算子です。

let x = 5;
let y = 2;

console.log(x + y); // 7
console.log(x - y); // 3
console.log(x * y); // 10
console.log(x / y); // 2.5

べき乗演算子

JavaScript には**というべき乗演算子があります。これは左のオペランドを基数とし、右のオペランドを指数とするべき乗計算を行います。

console.log(2 ** 3); // 8

単項プラス演算子

単項プラス演算子+は、オペランドの前に置かれます。数値に対しては何も影響を与えませんが、文字列を数値に変換する際に便利です。

console.log(+"123"); // 123

インクリメント演算子(++)

インクリメント演算子++は、オペランドの数値を 1 増加させます。前置インクリメント(++x)は増加後の値を返し、後置インクリメント(x++)は増加前の値を返します。

let x = 5;
console.log(++x); // 6

let y = 5;
console.log(y++); // 5
console.log(y); // 6

比較演算子

JavaScript には等価性をチェックするための比較演算子があります。== は抽象的な等価性をチェックし、=== は厳密な等価性をチェックします。

console.log(1 == "1"); // true
console.log(1 === "1"); // false

オプショナルチェーン(?.)

オプショナルチェーン ?. を使用すると、オブジェクトのプロパティが存在するかどうかを安全にチェックできます。

let person = {
  name: "Alice",
  address: {
    city: "Tokyo",
  },
};

console.log(person.address?.city); // "Tokyo"
console.log(person.job?.title); // undefined

オプショナルプロパティ(?)

オブジェクトの型に ? を追加すると、そのプロパティはオプショナル(必須ではない)になります。

type Person = {
  name: string
  age?: number
}

let alice: Person = { name: 'Alice' }
let bob: Person = { name: 'Bob', age: 20 }

Nullish coalescing 演算子(??)

Nullish coalescing 演算子 ?? を使うと、左側の値が null または undefined の場合に限り、右側の値を返します。

let value = null ?? "default"; // "default"

論理否定(!)

! 演算子を使うと、値の真偽値を反転させることができます。

let isNotTrue = !true; // false
let isNotFalse = !false; // true

let isDay = true; // 今が昼間だと仮定します
let isNotDay = !isDay; // これは「昼間ではない」を表すので、false になります

let isNight = false; // 今が夜ではないと仮定します
let isNotNight = !isNight; // これは「夜ではない」を表すので、true になります

OR 演算子(||)短絡評価

OR 演算子 (||) は、左辺が真なら左辺の値をそのまま返し、偽なら右辺を評価します。

const value = "左辺" || "右辺"; // "左辺"
const value = "" || "右辺"; // "右辺"

AND 演算子(&&)短絡評価

AND 演算子 (&&) は、左辺が真なら右辺を評価し、偽なら左辺の値をそのまま返します。

const value = "左辺" && "右辺"; // "右辺"
const value = "" && "右辺"; // ""

三項演算子(? :)

三項演算子 ? : を使うと、条件に基づいて 2 つの異なる値を返すことができます。

// 条件 ? 値1 : 値2
const value = true ? "値1" : "値2"; // "値1"
const value2 = false ? "値1" : "値2"; // "値2"

try...catch 構文

try...catch 構文を使うと、実行時のエラーを捕捉して処理することができます。

try {
  // エラーが発生する可能性のあるコード
} catch (error) {
  // エラーが発生したときの処理
}

find()

find() は配列内の要素をテストするために使われる関数を受け取ります。該当する最初の要素を見つけたら、それを返します。該当するものがなければ、undefined を返します。

const array = [1, 2, 3, 4, 5];
const found = array.find((element) => element > 3);
console.log(found); // 4

replace()

replace() メソッドは、文字列内の一部を新しい文字列に置き換えます。このメソッドは新しい文字列を返し、元の文字列は変更されません。

let str = "Hello, world!";
str = str.replace("world", "JavaScript");
console.log(str); // 'Hello, JavaScript!'

slice()

slice() メソッドは、配列の一部を浅くコピーして新しい配列オブジェクトを返します。元の配列は変更されません。

const array = [1, 2, 3, 4, 5];
const sliced = array.slice(1, 3);
console.log(sliced); // [2, 3]

filter()

filter() メソッドは、配列内の各要素をテストし、テストを通過したすべての要素から新しい配列を作成します。

const array = [1, 2, 3, 4, 5];
const filtered = array.filter((num) => num > 3);
console.log(filtered); // [4, 5]

concat()

concat() メソッドは、2 つまたはそれ以上の配列を結合して、新しい配列を作成します。

const array1 = ["a", "b", "c"];
const array2 = ["d", "e", "f"];
const array3 = array1.concat(array2);
console.log(array3); // ['a', 'b', 'c', 'd', 'e', 'f']

ジェネレータ

ジェネレータは特殊な関数で、一時停止して後で再開することができます。ジェネレータはfunction*キーワードを使用して定義します。

function* generateSequence() {
  yield 1;
  yield 2;
  return 3;
}

let generator = generateSequence();

console.log(generator.next()); // { value: 1, done: false }
console.log(generator.next()); // { value: 2, done: false }
console.log(generator.next()); // { value: 3, done: true }

yieldキーワードを使うことでジェネレータの実行を一時停止し、next()メソッドを使って再開することができます。

モジュール

JavaScript のモジュールは、コードを複数のファイルに分割する機能を提供します。モジュールはimportexportキーワードを使って他のモジュールと通信します。

// lib.js
export function hello() {
  return "Hello!";
}

// main.js
import { hello } from "./lib.js";

console.log(hello()); // "Hello!"

export default

export default を使うと、モジュールからデフォルトの値をエクスポートすることができます。

// greeting.js
export default function greet(name) {
  return "Hello, " + name + "!";
}

// app.js
import greet from "./greeting";
console.log(greet("Alice")); // "Hello, Alice!"

Fetch API

Fetch API は、ネットワークリクエストを行うためのモダンな JavaScript の API です。

fetch("https://api.example.com/data")
  .then((response) => response.json())
  .then((data) => console.log(data))
  .catch((error) => console.log("Error:", error));

非破壊的なメソッド

非破壊的なメソッドとは、オリジナルのデータを変更せずに新しいデータを作成するメソッドのことを指します。例えば、Array.prototype.slice()Array.prototype.concat()は非破壊的なメソッドです。

let originalArray = [1, 2, 3, 4, 5];
let slicedArray = originalArray.slice(1, 3);

console.log(originalArray); // [1, 2, 3, 4, 5]
console.log(slicedArray); // [2, 3]

async/await

JavaScript では非同期処理を行うために Promise がよく使われますが、async/awaitを使用すると非同期処理をより直感的に書けます。

async function fetchUser() {
  let response = await fetch("https://api.example.com/user");
  let user = await response.json();
  return user;
}

e.target.value

JavaScript における e.target.value は、イベントをトリガーした要素(ユーザーが直接対話した HTML 要素)の現在の値を取得するための一般的な方法です。この表記法は、特にフォーム要素(テキストボックスやドロップダウンメニューなど)の値を取得する際に頻繁に使用されます。

例えば、HTML のテキストボックスからユーザーが入力した値を取得するためには以下のようにします。

document.querySelector("input").addEventListener("input", function (e) {
  console.log(e.target.value);
});

このコードでは、'input'というタグ名を持つ要素に対してイベントリスナーを追加しています。ユーザーがテキストボックスに何か入力すると、それに反応して 'input' イベントが発生し、上記の関数が実行されます。この関数では、イベントオブジェクト e を引数として受け取り、その target プロパティ(イベントをトリガーした要素)の value プロパティ(その要素の現在の値)をコンソールに出力します。

Symbol

Symbol は ES6 から導入された新たなプリミティブ型です。Symbol はユニークで不変の値を生成します。それぞれの Symbol 値は他のどの Symbol 値とも完全に異なります。これは、Symbol が常にユニークな値を提供するためです。

let sym1 = Symbol();
let sym2 = Symbol();

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

上記の例では、sym1sym2 はそれぞれ新たに生成された Symbol ですが、それぞれが完全に異なる値を持つため、比較した結果は false となります。

また、Symbol を生成する際にはオプションで文字列を引数として渡すことができます。この文字列は説明として使われ、デバッグに役立つ情報を提供しますが、Symbol の一意性に影響は与えません。

let sym1 = Symbol("symbol for key");
let sym2 = Symbol("symbol for key");

console.log(sym1 === sym2); // false
console.log(sym1.toString()); // "Symbol(symbol for key)"
console.log(sym2.toString()); // "Symbol(symbol for key)"

ここでは、sym1sym2 はそれぞれ同じ説明を持つ Symbol を生成しています。しかし、これらの Symbol の値はそれぞれ異なるため、比較した結果は false となります。また、toString() メソッドを使って Symbol の説明を文字列として取得することができます。

Symbol はオブジェクトのキーとしてよく使用されます。これは、Symbol が常にユニークな値を提供するため、意図しないキーの衝突を避けることができるからです。

let sym = Symbol("symbol for key");
let obj = {};

obj[sym] = "value for key";
console.log(obj[sym]); // "value for key"

ここでは、新たに生成した Symbol をキーとして使用してオブジェクトに値を設定しています。その後、同じ Symbol を使って値を取得することができます。

初心者に分かりやすい!JavaScript 入門チートシート