Для чего нужен тип Symbol в JavaScript?
Что проверяют
Знаете ли вы, что Symbol это примитив для уникальных ключей и протоколов языка, а не способ спрятать данные. Следом обычно спрашивают про Symbol.for, про well-known символы и про то, видны ли символьные ключи в JSON.stringify.
Как отвечать
Symbol появился в ES2015, typeof для него возвращает 'symbol'. Главное:
- уникальность:
Symbol('id') !== Symbol('id'), описание нужно для отладки и доступно через.description. Конструктора нет,new Symbol()бросаетTypeError; - ключи без конфликтов: библиотека может добавить в чужой объект свойство, которое не пересечётся со строковыми ключами пользователя;
- невидимость для обычного перебора: символьные ключи пропускают
for...in,Object.keysиJSON.stringify, но их отдаютObject.getOwnPropertySymbolsиReflect.ownKeys. Это защита от случайных коллизий, а не приватность; - глобальный реестр:
Symbol.for('app.key')возвращает один и тот же символ по строке во всём процессе, даже между контекстамиvm, аSymbol.keyForделает обратное. В Node это спасает, когда вnode_modulesоказались две копии одной библиотеки и обычные символы у них разные; - well-known символы:
Symbol.iteratorделает объект перебираемым вfor...of,Symbol.asyncIteratorработает вfor await, так и читают потоки:for await (const chunk of readable). Ещё естьSymbol.toPrimitive,Symbol.toStringTag,Symbol.hasInstance.
Пример из Node: util.inspect.custom это Symbol.for('nodejs.util.inspect.custom'). Метод под этим ключом задаёт, как объект выглядит в console.log, и не мешает сериализации.
Где спотыкаются
Называют символьные свойства приватными. Любой код достанет их через Reflect.ownKeys. Для настоящей приватности нужны поля #field или замыкание.
Удивляются, что символьные ключи пропали после JSON.stringify и не доехали в ответе API.
Склеивают символ со строкой: ` id: ${sym} бросает TypeError, нужно явное String(sym) или sym.description`.