Что такое Symbol

Ответ

Symbol — это уникальный и неизменяемый примитивный тип данных, который может использоваться как идентификатор для свойств объектов.

Особенности:

  • Каждый Symbol уникален, даже если создан с одинаковым описанием:

    const sym1 = Symbol('foo');
    const sym2 = Symbol('foo');
    console.log(sym1 === sym2); // false
  • Не участвует в автоматическом приведении типов (toString() нужно вызывать явно).

  • Часто используется для создания "скрытых" свойств объектов, чтобы избежать конфликтов имён.

Пример:

const id = Symbol('id');
const user = {
  name: 'Alex',
  [id]: 123 // Свойство не видно в for..in
};
console.log(user[id]); // 123

Глобальные Symbol:
Можно создавать глобальные символы через Symbol.for(key), которые доступны во всей программе.

Ответ 18+ 🔞

О, слушай, про символы в JavaScript, это ж просто пиздец какой-то интересный прикол, внатуре.

Вот представь себе: есть у тебя обычные типы — числа, строки, булево говно. А потом бац — и появляется этот самый Symbol. Это как будто примитив, но не совсем, блядь. Его главная фишка — он уникальный и неизменяемый. Создал один символ — и второго такого же, сука, в природе не существует, даже если ты попытаешься.

Смотри, вот тебе классика жанра, от чего мозг может ебнуться:

const sym1 = Symbol('foo');
const sym2 = Symbol('foo');
console.log(sym1 === sym2); // false

Видишь? Оба созданы с описанием 'foo', но они НЕ РАВНЫ. Каждый — это как отпечаток пальца, ёпта, или как уникальный серийный номер на хуйню. sym1 — это один кусок уникальности, sym2 — совсем другой. Сравниваешь — получаешь false, и волнение ебать, как так-то?

А зачем это всё, спросишь? А вот зачем, хитрая жопа: чтобы делать скрытые свойства у объектов. Ты же знаешь, как это бывает: пишешь библиотеку, добавляешь в объект своё служебное поле _id, а потом какой-нибудь пидарас-пользователь берёт и случайно (или нарошно!) перезаписывает его своим _id, и всё, пиздец, накрылось медным тазом, логика сломалась.

Вот символы и спасают. Свойство, ключом которого является символ, не видно в обычных итерациях типа for..in. Оно как будто в параллельной реальности существует.

Смотри, как это выглядит:

const id = Symbol('id'); // Вот он, наш уникальный ключ-невидимка
const user = {
  name: 'Alex',
  [id]: 123 // Записываем значение по символьному ключу. Обрати внимание на квадратные скобки, это важно!
};
// Теперь попробуй пройтись по объекту
for (let key in user) console.log(key); // Выведет только 'name'. Свойство [id] — него не видно, оно спрятано!
// Но получить-то его можно, если знать секретный ключ!
console.log(user[id]); // 123

Вот так вот, блядь. Свойство есть, значение есть, а в обычных циклах его нихуя не видно. Красота, да? Идеально для всяких внутренних служебных меток.

А ещё есть, блядь, глобальные символы — это вообще отдельная песня. Если обычный Symbol('key') создаёт новую уникальность каждый раз, то Symbol.for('key') сначала проверяет: а нет ли уже в каком-то глобальном реестре символа с таким именем? Нет — создаёт и кладёт туда. Есть — просто возвращает существующий. Это как единая база уникальных ключей на всю программу. Удобно, когда нужно, чтобы один и тот же символ использовался в разных частях кода, а не плодить их, как сука, овердохуища одинаковых.

Короче, символы — это мощный инструмент, чтобы делать по-настоящему уникальные метки и прятать implementation details от посторонних глаз. Сначала кажется, что хуйня какая-то, а потом понимаешь — о, а это гениально, блядь.