- Символ
- Кратко
- Как пишется
- Создание
- Использование
- Системные символы
- Глобальный реестр символов
- На собеседовании
- Что такое стратегия?
- Выполнение задачи
- Пример работы
- Что хотят проверить?
- Symbol
- Синтаксис
- Параметры
- Описание
- Разделяемые символы в глобальном символьном реестре
- Поиск символьных свойств у объектов
- Свойства
- Известные символы
- Итерационные символы
- Символы регулярных выражений
- Другие символы
- Методы
Символ
Примитивный тип, представляющий собой уникальный идентификатор. Используется как имя свойств в объектах.
Время чтения: меньше 5 мин
Обновлено 20 декабря 2021
Кратко
Скопировать ссылку «Кратко» Скопировано
Символ ( Symbol ) — примитивный тип, значения которого создаются с помощью вызова функции Symbol . Каждый созданный символ уникален.
Символы могут использоваться в качестве имён свойств в объектах. Символьные свойства могут быть прочитаны только при прямом обращении и не видны при обычных операциях.
Как пишется
Скопировать ссылку «Как пишется» Скопировано
Создание
Скопировать ссылку «Создание» Скопировано
Для создания символа нужно вызвать функцию Symbol :
const sym = Symbol()const symTwo = Symbol() console.log(sym === symTwo)// false
const sym = Symbol() const symTwo = Symbol() console.log(sym === symTwo) // false
Создание символа через конструктор new Symbol ( ) не поддерживается.
При создании символа первым аргументом можно передать его описание. Оно ни на что не влияет и необходимо только для отладки. Даже если описания символов совпадают, JavaScript всё равно создаёт уникальные символы:
const sym = Symbol('name')const symTwo = Symbol('name') console.log(sym === symTwo)// false
const sym = Symbol('name') const symTwo = Symbol('name') console.log(sym === symTwo) // false
Использование
Скопировать ссылку «Использование» Скопировано
Символы используются для создания скрытых свойств объектов. В отличие от свойств, ключом которых является строка, символьные свойства может читать только владелец символа. Скрытые свойства не видны при его обходе с помощью for . . . in :
const secondaryId = Symbol() const user = 'id': 193, 'name': 'Ольга', [secondaryId]: 'olga-1'> for (const prop in user) console.log(prop, user[prop])>// id 193// name Ольга console.log(user[secondaryId])// olga-1
const secondaryId = Symbol() const user = 'id': 193, 'name': 'Ольга', [secondaryId]: 'olga-1' > for (const prop in user) console.log(prop, user[prop]) > // id 193 // name Ольга console.log(user[secondaryId]) // olga-1
Это может пригодиться, когда необходимо добавить свойства объекту, который могут модифицировать другие части программы. Таким образом только вы сможете читать созданное свойство, а гарантия уникальности символов гарантирует и отсутствие конфликтов имён.
Системные символы
Скопировать ссылку «Системные символы» Скопировано
Символы активно используются внутри самого JavaScript, чтобы определять поведение объектов. Такие символы называются «хорошо известными» (well-known symbols).
Самый известный символ Symbol . iterator , который позволяет реализовать обход конструкции с помощью синтаксических конструкций for . . of и спред-синтаксиса.
Полный список таких символов доступен в спецификации, но на практике он нужен нечасто.
Глобальный реестр символов
Скопировать ссылку «Глобальный реестр символов» Скопировано
Созданный символ уникален, но как быть, если он нужен в нескольких местах программы? Для решения этой проблемы существует глобальный реестр символов, он хранит символы по строковым ключам. При обращении по ключу всегда будет возвращаться один и тот же символ.
Работа с реестром символов организована с помощью двух методов:
- Symbol . for ( ключ ) — возвращает символ, хранящийся по ключу. Если символа ещё не существует, он создаётся автоматически.
- Symbol . keyFor ( символ ) — возвращает строковый ключ, который хранит переданный символ или undefined , если символ не хранится в реестре.
const secondaryId = Symbol() const user = 'id': 193, 'name': 'Ольга', [secondaryId]: 'olga-1'> console.log(Symbol.keyFor(secondaryId))// undefined const newSym = Symbol.for('registryKey')const newestSym = Symbol.for('registryKey')console.log(newSym === newestSym)// true user[newSym] = 'hello'console.log(Symbol.keyFor(newSym))// registryKey
const secondaryId = Symbol() const user = 'id': 193, 'name': 'Ольга', [secondaryId]: 'olga-1' > console.log(Symbol.keyFor(secondaryId)) // undefined const newSym = Symbol.for('registryKey') const newestSym = Symbol.for('registryKey') console.log(newSym === newestSym) // true user[newSym] = 'hello' console.log(Symbol.keyFor(newSym)) // registryKey
На собеседовании
Скопировать ссылку «На собеседовании» Скопировано
Напишите свой класс, который бы являлся стратегией к функции split, используя Symbol. Пример:
Скопировать ссылку «Напишите свой класс, который бы являлся стратегией к функции split, используя Symbol. Пример:» Скопировано
console.log('urlsomePath'.split(new Split1('url'))); // "url/somePath"console.log('somePathurlAnother'.split(new Split1('url'))); // "url/somePath/url/Another"
console.log('urlsomePath'.split(new Split1('url'))); // "url/somePath" console.log('somePathurlAnother'.split(new Split1('url'))); // "url/somePath/url/Another"
Скопировать ссылку «Danil Solomin отвечает» Скопировано
Что такое стратегия?
Скопировать ссылку «Что такое стратегия?» Скопировано
Стратегия (Strategy) — это ООП поведенческий шаблон проектирования, который позволяет расширять базовый класс или метод новым функционалом. Для этого нужно передать в него, так называемый, конкретный класс. Например:
const Clock = new Clock // Создаем базовую версию часовconst GoldenClock = new Clock(new GoldenParts) // Часы с золотым оформлениемconst WoodenClock = new Clock(new WoodenParts) // Часы с деревянным оформлением Clock.draw() // Рисуем стандартную версию часовGoldenClock.draw() // Метод тот же, что и строкой выше, но теперь мы используем золотое оформлениеWoodenClock.draw() // Используем деревянное оформление
const Clock = new Clock // Создаем базовую версию часов const GoldenClock = new Clock(new GoldenParts) // Часы с золотым оформлением const WoodenClock = new Clock(new WoodenParts) // Часы с деревянным оформлением Clock.draw() // Рисуем стандартную версию часов GoldenClock.draw() // Метод тот же, что и строкой выше, но теперь мы используем золотое оформление WoodenClock.draw() // Используем деревянное оформление
Выполнение задачи
Скопировать ссылку «Выполнение задачи» Скопировано
Чтобы написать такой класс нам понадобится специальный well-known символ [ Symbol . split ] . Метод split ( ) вызывает функцию [ Symbol . split ] ( str ) , а результат вызова возвращает как результат split ( ) . У строк это уже реализовано:
"123,4,56".split(",") // ["123", "4", "56]
"123,4,56".split(",") // ["123", "4", "56]
Мы можем добавить такое же поведение к своему классу:
class MySplit constructor(value) this.value = value; // Принимаем строку по которой будем сплитить > [Symbol.split](string) < // принимаем строку-аргумент (которую будем сплитить) // В конце необходимо вернуть полученный результат, иначе split() вернет undefined >>
class MySplit constructor(value) this.value = value; // Принимаем строку по которой будем сплитить > [Symbol.split](string) // принимаем строку-аргумент (которую будем сплитить) // В конце необходимо вернуть полученный результат, иначе split() вернет undefined > >
Для нашей задачи разобьём строку при помощи регулярного выражения:
[Symbol.split](string) // Заменяем все вхождения this.value на /$/ let index = string.replace(new RegExp(this.value, "g"), `/$/`); // убираем первый слэш, /url/Path -> url/Path if (index[0] === "/") index = index.substr(1) // Строка должна начинаться с url/, даже если его не было в начале if (!index.startsWith(this.value)) index = `$/` + index; return index;>
[Symbol.split](string) // Заменяем все вхождения this.value на /$/ let index = string.replace(new RegExp(this.value, "g"), `/$this.value>/`); // убираем первый слэш, /url/Path -> url/Path if (index[0] === "/") index = index.substr(1) // Строка должна начинаться с url/, даже если его не было в начале if (!index.startsWith(this.value)) index = `$this.value>/` + index; return index; >
Пример работы
Скопировать ссылку «Пример работы» Скопировано
"foobarfoobaz".split(new MySplit("foo")) // "foo/var/foo/baz""foobarfoobaz".split(new MySplit("bar")) // "bar/foo/bar/foobaz"
"foobarfoobaz".split(new MySplit("foo")) // "foo/var/foo/baz" "foobarfoobaz".split(new MySplit("bar")) // "bar/foo/bar/foobaz"
Что хотят проверить?
Скопировать ссылку «Что хотят проверить?» Скопировано
Этот вопрос проверяет умеете ли вы использовать символы. Хотя такие вопросы задают редко, из-за специфичности темы, умение пользоваться символами – полезный инструмент, который вам обязательно пригодится.
Symbol
Символ (анг. Symbol) — это уникальный и неизменяемый тип данных, который может быть использован как идентификатор для свойств объектов. Символьный объект (анг. symbol object) — это объект-обёртка (англ. wrapper) для примитивного символьного типа.
Синтаксис
Параметры
Необязательный, строка. Описание символа, которое может быть использовано во время отладки, но не для доступа к самому символу.
Описание
Чтобы создать новый символьный примитив, достаточно написать Symbol() , указав по желанию строку в качестве описания этого символа:
var sym1 = Symbol(); var sym2 = Symbol("foo"); var sym3 = Symbol("foo");
Код выше создаёт три новых символа. Заметьте, что Symbol(«foo») не выполняет приведение (англ. coercion) строки «foo» к символу. Это выражение создаёт каждый раз новый символ:
Symbol("foo") === Symbol("foo"); // false
Код ниже с оператором new бросит исключение TypeError :
var sym = new Symbol(); // TypeError
Это удерживает разработчиков от создания явного объекта-обёртки Symbol вместо нового символьного значения. Создание явных объектов-обёрток для примитивных типов доступно (например, new Boolean , new String , new Number ).
Если вам действительно необходимо обернуть символ в объект, вы можете использовать функцию Object() :
var sym = Symbol("foo"); typeof sym; // "symbol" var symObj = Object(sym); typeof symObj; // "object"
Разделяемые символы в глобальном символьном реестре
Приведённый выше синтаксис, использующий функцию Symbol(), не создаст глобальный символ, который был бы доступен в любом месте вашего кода. Для создания символов, доступных во всех файлах и в окружении (глобальной области), используйте методы Symbol.for() и Symbol.keyFor() , чтобы задать или получить символ из глобального символьного реестра.
Поиск символьных свойств у объектов
Метод Object.getOwnPropertySymbols() возвращает массив символов и позволяет получить символьные свойства конкретного объекта. Следует заметить, что при инициализации объекты не получают символьных свойств, так что этот массив будет пуст, пока вы не зададите ему какое-либо символьное свойство.
Свойства
Содержит длину, всегда равную 0 (нулю).
Содержит прототип конструктора Symbol .
Известные символы
В добавок к вашим собственным символам, JavaScript имеет несколько встроенных символов, представляющих внутренние механизмы языка, которые не были доступны разработчикам в версиях ECMAScript 5 и более ранних. Эти символы доступны посредством следующих свойств:
Итерационные символы
Метод, возвращающий итератор по умолчанию для объекта. Используется конструкцией for. of .
Символы регулярных выражений
Метод для сопоставления объекта со строкой, также используемый для определения возможности объекта выступать в качестве регулярного выражения. Используется функцией String.prototype.match() .
Метод, заменяющий совпавшие подстроки в строке. Используется функцией String.prototype.replace() .
Метод, возвращающий индекс вхождения подстроки, соответствующей регулярному выражению. Используется функцией String.prototype.search() .
Метод, разбивающий строку на части в местах, соответствующих регулярному выражению. Используется функцией String.prototype.split() .
Другие символы
Метод, определяющий, распознает ли конструктор некоторый объект как свой экземпляр. Используется оператором instanceof .
Булево значение, показывающее, должен ли объект быть сведён к плоскому представлению (англ. flatten) в виде массива его элементов функцией Array.prototype.concat() .
Массив строковых имён свойств. Позволяет скрыть свойства от инструкции with (прежде всего для обратной совместимости).
Метод, определяющий конструктор для порождённых объектов.
Метод, преобразующий объект в примитив (примитивное значение).
Строковое значение, используемое в качестве описания объекта по умолчанию. Используется функцией Object.prototype.toString()
Методы
Ищет существующие символы по заданному ключу и возвращает его, если он найден. В противном случае создаётся новый символ для данного ключа в глобальном реестре символов.
Получает по разделяемому символу его ключ из глобального реестра символов.