Типы символов в JavaScript

В общем случае, ключи свойств объекта могут быть двух типов: строка и символ. Символы - это в конечном итоге уникальные идентификаторы. Они могут быть созданы с помощью функции-фабрики Symbol().

Например:

javascript symbol

После создания символа, вы можете дать ему имя или описание. Это особенно полезно для практик отладки. Давайте посмотрим на следующий пример:

//  id is a symbol, it's a description "id"
let id = Symbol("id");

Как мы уже отмечали, символы являются уникальными. Даже когда вы создаете различные символы с одним и тем же именем, они считаются разными символами.

Помните, что описания и имена являются лишь метками, не влияющими на что-либо.

Вот пример:

Javascript symbol type
let mySymbol1 = Symbol("mySymbol"); let mySymbol2 = Symbol("mySymbol"); console.log(mySymbol1 == mySymbol2); // false

В приведенном выше случае два символа имеют одинаковое описание, но они не равны.

Важно знать, что автоматическое преобразование символов в строку невозможно.

Например, это alert приведет к ошибке:

Javascript symbol type
let mySymbol = Symbol("mySymbol"); console.log(mySymbol); // TypeError: Cannot convert a Symbol value to a string

Чтобы показать символ, вам нужно явно вызвать на нем .toString(), как показано ниже:

javascript symbol type
let mySymbol = Symbol("mySymbol"); console.log(mySymbol.toString()); // Symbol(mySymbol), now it works

Чтобы получить свойство symbol.description, вызовите:

Javascript symbol description
let mySymbol = Symbol("mySymbol"); console.log(mySymbol.description); // mySymbol

О “скрытых” свойствах

С помощью символов вы легко можете создать так называемые “скрытые” свойства объекта. Невозможно получить доступ или перезаписать другие части кода.

В случае, если вы работаете с объектами сайта, принадлежащими стороннему коду, вам нужно будет добавить к ним идентификаторы. Для этого необходимо использовать ключ символа, как показано ниже:

Javascript symbol key
let site = { // belongs to another code name: "W3Docs" }; let id = Symbol("id"); site[id] = 1; console.log(site[id]); // we can access the data using the symbol as the key

В другом случае, когда другой скрипт хочет иметь свой идентификатор внутри сайта.

Это может быть другая библиотека JavaScript, так что скрипты ничего не знают друг о друге.

Таким образом, этот скрипт может создать свой Symbol("id").

Например:

// ...
let id = Symbol("id");
site[id] = "Their id value";

Символы в литерале

Чтобы использовать символ в литерале объекта, необходимо вставить квадратные скобки вокруг него.

Просто посмотрите на этот пример:

Javascript symbol
let id = Symbol("id"); let site = { name: "W3Docs", [id]: 100 // not "id: 100" }; console.log(site[id]);

Это связано с тем, что вам нужно значение из переменной id в качестве ключа, а не строки “id”.

Цикл for...in пропускает символы

Цикл for..in не учитывает символьные свойства. Вот пример:

Javascript symbol for..in loop
let id = Symbol("id"); let site = { name: "W3Docs", [id]: 10 }; for (let key in site) { console.log(key); // name , no symbols } console.log("Direct: " + site[id]); // works the direct access by the symbol

Глобальные символы

Как мы уже упоминали, символы уникальны, даже если у них одно и то же описание. Но иногда вам может понадобиться, чтобы символы с одинаковыми именами были одними и теми же сущностями. Например, различные части вашего приложения хотят получить доступ к символу "id", который означает ту же самую свойство.

Для этого существует глобальный реестр символов. Он позволяет создавать символы внутри него и получать доступ к ним позднее. Более того, он гарантирует, что непрерывные обращения с одним и тем же именем показывают точно тот же символ. Для чтения символа из глобального реестра вам рекомендуется использовать Symbol.for(key).

Этот вызов помогает проверить глобальный реестр. Затем, если есть символ, определенный как ключ, он будет возвращен. В противном случае будет создан новый символ Symbol(key) и сохранен в реестре под определенным ключом.

Это демонстрируется в примере ниже:

Javascript symbol.for the global registry
// read from the global registry let id = Symbol.for("id"); // if this the symbol did not exist, it's created // read it again let idAgain = Symbol.for("id") // the same symbol console.log(id === idAgain); // true

Символы, которые находятся в реестре, известны как глобальные символы. Вы можете использовать их, когда хотите всемирный символ, который имеет запись везде в коде.

Symbol.keyFor

Можно использовать обратный вызов для глобальных символов. Вы можете сделать это с помощью Symbol.keyFor(sym). Он сделает обратное: вернет имя по глобальному символу.

Для лучшего понимания ознакомьтесь с следующим примером:

Javascript global symbol
// get symbol by name let sym1 = Symbol.for("siteName"); let sym2 = Symbol.for("id"); // get name by symbol console.log(Symbol.keyFor(sym1)); // siteName console.log(Symbol.keyFor(sym2)); // id

Symbol.keyFor будет работать исключительно для глобальных символов. В случае, если символ окажется не глобальным, не будет возможности его найти и вернуть undefined. Другими словами, каждый символ имеет свойство описание.

Например:

Javascript symbol description
let globalSymbol = Symbol.for("name"); let localSymbol = Symbol("name"); console.log(Symbol.keyFor(globalSymbol)); // name, global symbol console.log(Symbol.keyFor(localSymbol)); // undefined, not global console.log(localSymbol.description); // name

Системные символы

Внутри JavaScript используется множество системных символов.

Вот некоторые из них:

  1. Symbol.hasInstance
  2. Symbol.iterator
  3. Symbol.isConcatSpreadable
  4. Symbol.toPrimitive

Есть много других системных символов, также.

Например, Symbol.toPrimitive предназначен для описания преобразования объекта в примитив.

Symbol.isConcatSpreadable можно описать как довольно специфический символ. Он регулирует поведение Array#concat..

Резюме

В JavaScript символы гарантируют уникальность уровня доступа к объектам. Всем разработчикам необходимо иметь базовое понимание символов и их вариантов использования.

Технически, символы не совсем скрыты. Встроенный метод Object.getOwnPropertySymbols(obj) позволит вам получить все символы. Существует другой метод, называемый Reflect.ownKeys(obj),, который предназначен для возвращения всех ключей объекта, включая символические. Тем не менее, большинство библиотек, синтаксических конструкций и встроенных функций избегают использования упомянутых методов.

Время Викторины: Проверьте Свои Навыки!

отовы проверить свои знания? Погрузитесь в наши интерактивные викторины для более глубокого понимания и веселого способа закрепить знания.

Считаете ли это полезным?