TypeScript Symbol

Symbol — это примитивный тип данных, появившийся в ES6 и представляющий уникальный идентификатор.

В TypeScript Symbol можно использовать в качестве ключа свойства объекта, что обеспечивает уникальность свойств.

Это очень полезно в таких сценариях, как создание приватных свойств и предотвращение конфликтов имён свойств.


Диаграмма SVG: как работает Symbol Background Title Symbol Characteristics Symbol Creation Created with Symbol() var sym1 = Symbol("key") var sym2 = Symbol("key") // sym1 !== sym2 Unique each time it is created Arrow Object Property Used as an object property key var obj = { [sym]: "value" } // Unique property name Arrow Global Registration Symbol.for() Global Registry Same key Equal Lower section: Built-in Symbols Common built-in Symbols Built-in Symbol 1 Symbol.iterator - Iterator Built-in Symbol 2 Symbol.toStringTag - Object description Built-in Symbol 3 Symbol.hasInstance - instanceof Arrow marker

Зачем нам нужен Symbol?

В JavaScript имена свойств объекта всегда являются строками, что иногда может приводить к конфликтам.

Symbol предоставляет способ создания уникальных идентификаторов. Каждый вызов Symbol() создаёт новое уникальное значение.

Это очень полезно в таких сценариях, как создание приватных свойств, определение уникальных констант и реализация итераторов.

Объяснение концепции:Symbol — один из примитивных типов данных JavaScript, создаваемый с помощью функции Symbol(). Каждое значение Symbol уникально; даже если их описания совпадают, они не равны.


Создание Symbol

Используйте функцию Symbol() для создания уникального значения Symbol.

Пример

// Создать Symbol, передав строку описания (необязательно)
var sym1 = Symbol("description");
var sym2 = Symbol("description");

// Каждый созданный Symbol уникален, даже если описания одинаковы
console.log("sym1 === sym2: " + (sym1 === sym2));
console.log("sym1: " + sym1.toString());

Вывод:

sym1 === sym2: false
sym1: Symbol(description)

Уникальность:Это самая важная особенность Symbol. Каждый вызов Symbol() создаёт новое значение, которое не равно никакому другому значению.


Symbol как свойство объекта

Symbol можно использовать в качестве ключа свойства объекта, чтобы создать уникальное имя свойства.

Пример

// Создаём Symbol как ключ свойства
var sym = Symbol("key");

// Используйте Symbol как ключ свойства объекта
var obj = {
    name: "Alice",  // Обычное строковое свойство
    [sym]: "secret value"  // Свойство-символ, вычисляемое имя свойства
};

// Доступ к обычному свойству
console.log("Обычное свойство: " + obj.name);
// Доступ к свойству-символу
console.log("Свойство-символ: " + obj[sym]);
// Свойства-символы не появляются в JSON
console.log("Объект: " + JSON.stringify(obj));

Вывод:

普通属性: Alice
Symbol 属性: secret value
对象: {"name":"Alice"}

Приватность:Свойства-символы не появляются в JSON-сериализации и не перебираются циклом for...in, поэтому их можно использовать для создания «приватных» свойств.


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

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

Пример

// Используйте метод Symbol.for для создания/получения глобального символа
// Если ключ не существует, создаётся новый; если он уже существует, возвращается существующий
var globalSym1 = Symbol.for("global");
var globalSym2 = Symbol.for("global");

// Символы с одинаковым ключом равны
console.log("Глобальные символы равны: " + (globalSym1 === globalSym2));

// Получить ключ символа
console.log("Ключ символа: " + Symbol.keyFor(globalSym1));

Вывод:

全局 Symbol 相等: true
Symbol key: global

Разница:Symbol() создаёт новое значение каждый раз, тогда как Symbol.for() ищет или создаёт в глобальном реестре.


Встроенные символы

JavaScript определяет некоторые встроенные значения Symbol для настройки поведения языка.

Пример

// Symbol.iterator используется для определения итератора объекта по умолчанию
var arr = [1, 2, 3];
// Получить итератор массива
var iterator = arr[Symbol.iterator]();

// Пройти с помощью итератора
console.log("Первый элемент: " + iterator.next().value);
console.log("Второй элемент: " + iterator.next().value);

// Symbol.toStringTag настраивает возвращаемое значение метода toString() объекта
var obj = {
    [Symbol.toStringTag]: "MyObject"
};
console.log("Тип объекта: " + obj.toString());

Вывод:

第一个元素: 1
第二个元素: 2
Object type: [object MyObject]

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


Аннотация типа Symbol

Используйте тип Symbol для аннотации типов в TypeScript.

Пример

// Аннотация типа Symbol
var sym: symbol = Symbol("key");

// Тип ключа объекта — symbol, а тип значения — string
var obj: { [key: symbol]: string } = {};

// Использовать Symbol в качестве ключа
obj[sym] = "value";
console.log("Значение свойства Symbol: " + obj[sym]);

Тип:В TypeScript,symbolзначения Symbol аннотируются типами.


Примечания

  • Уникальность:Значение каждого вызова Symbol() отличается от других
  • Неперечислимость:Свойства Symbol не появляются в циклах for...in
  • JSON игнорирует:Свойства Symbol не сериализуются в JSON
  • Глобальная регистрация:Symbol.for() использует общий глобальный реестр

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


Итог

Symbol — важный примитивный тип в TypeScript.

  • Уникальность:Каждый созданный Symbol не равен остальным
  • Ключ свойства:Может использоваться как уникальный ключ свойства для объектов
  • Глобальная регистрация:Symbol.for() создаёт/извлекает глобальные символы
  • Встроенные символы:Symbol.iterator, Symbol.toStringTag и т. д.
  • Аннотация типа:Используйте тип symbol

Рекомендация:Используйте Symbol, когда вам нужно создавать уникальные идентификаторы, избегать конфликтов имён свойств или нужны «приватные» свойства.

Другие расширения