Що таке Symbol? Для чого він? Які задачі вирішує? Гайда розбиратися.
Символи — це особливі примітиви, які гарантують максимальну унікальність значення. Настільки максимальну, що
Symbol('foo') !== Symbol('foo'). Оця текстова мітка — по суті просто ваша примітка до змінної, а не частина самого значення.Символи дозволяють уникати конфліктів у ключах обʼєкта. Навіть якщо у вас символздєсь і символздєсь — це завжди різні значення. Ви можете абсолютно спокійно робити таке (тільки от нашо?):
const object = {
[Symbol("підпиздєсь")]: "foo",
[Symbol("підпиздєсь")]: "bar"
};А доступитися до конкретної властивості, захованої за символом, можна тільки маючи посилання на сам символ.
Symbol — це єдиний примітив, який можна використовувати як ключ до обʼєкта без перетворення на рядок. Інші примітиви, як-от числа чи булеві значення, автоматично зводяться до рядків.
Найскладніше в роботі з Symbol — це прийняти, що вони поводяться інакше, ніж звичні примітиви. Рядки, числа, логічні значення — змінюються, копіюються, порівнюються напряму. Символи ж — щось з квантової механіки, коли це ніби і примітив, а водночас і значення за посиланням. І якщо загубити його — то вже не знайти, бо створити такий самий буде неможливо (ну майже).
Символи неперелічувані — їх не видно в Object.keys, for...in, JSON.stringify. Але можна дістати через Object.getOwnPropertySymbols(obj) або Object.getOwnPropertyDescriptors(obj).
Це тому, що символи створені не для приватности як такої, а, радше, для прихованости та запобіганню випадкових перевизначень. Тобто часткової приватности.
До речі, про унікальність. Існує API Symbol.for(), яке дозволяє створювати загальнодоступні символи з єдиною ідентичністю, які зберігаються в глобальному реєстрі
const here = Symbol.for('підпиздєсь');
const there = Symbol.for('підпиздєсь');
console.log(here === there); // trueТакож існують так звані well-known Symbols, які працюють як API-хуки: ті ж Symbol.iterator, Symbol.toStringTag, які дозволяють описувати власні імплементації для певних поведінок. Наприклад, описавши метод [Symbol.iterator] у класі або обʼєкті, ми зробимо такий обʼєкт Iterable.
Швидше за все, ви не будете стикатися з ними щодня. Хіба ви розробляєте якусь бібліотеку або рішення, в якому надзвичайно важлива інкапсуляція на рівні обʼєктів.
🔗 MDN
Зізнавайтесь, хоч трошки зрозуміли, що таке Symbol? І обовʼязково поділіться своїм досвідом роботи з ним в коментарях (навіть якщо й не зрозуміли)!
@babichdev
Вподобайки, поширення — я про це вже не мав би вам нагадувать ;)
***
📣 Нагадую, що завтра (27.05) чекатиму вас на затишній дискусії про Clean Code vs Good Enough Code у Львові! Приходьте самі та запрошуйте колег!