Symbol
Symbol - это уникальный и неизменяемый тип данных, который может быть использован как идентификатор для свойств объектов.
1Symbol() === Symbol() //false
Мы можем переделать параметр в Symbol
который будет использоваться как описание символа
1console.log(Symbol()) //Symbol()2console.log(Symbol('Test')) //Symbol(Test)
Symbol созданные с одинаковым описанием так же будут не равны друг другу
1Symbol("foo") === Symbol("foo"); // false
Это происходит потому что: Symbol("foo")
не выполняет приведение строки foo к символу. Это выражение создает каждый раз новый символ.
Если мы хотим обь явить символ через new
то получим исключение
1const description = new Symbol('description'); // TypeError Symbol is not a constructor
Это удерживает разработчиков от создания явного объекта-обёртки Symbol вместо нового символьного значения.
Когда используют символы:
- Символы часто используются для идентификации свойств объекта.
- Чтобы избежать конфликта имен между свойствами, так как ни один символ не равен другому.
- Добавить свойства, которые пользователь не может перезаписать, намеренно или не осознавая.
- Создать приватные свойства в классе.
1const NAME = Symbol();23const person = {4 [NAME]: 'John'5}67person[NAME] //'John'8const RUN = Symbol()9person[RUN] = () => 'Person is running';10console.log(person[RUN]()) //'Person is running'
- Символы не перечисляются, это означает, что они не включаются в цикл
for..of
илиfor..in
, запущенный для объекта. - Символы не являются частью результата
Object.keys()
илиObject.getOwnPropertyNames()
. - Можно получить доступ ко всем символам, назначенным объекту, используя метод
Object.getOwnPropertySymbols()
.
1const dog = {};23const r = Symbol('Roger');4const s = Symbol('Syd');56dog[r] = {7 name: 'Roger',8age: 69}1011dog[s] = {12 name: 'Syd',13 age: 514}1516console.log(Object.getOwnPropertySymbols(dog)) //[ Symbol(Roger), Symbol(Syd) ]
Методы
Symbol.for(key)
Метод Symbol.for(key)
ищет ранее созданный разделяемый символ по заданному ключу и возвращает его, если он найден.
В противном случае создается новый разделяемый символ для данного ключа в глобальном реестре символов.
1Symbol.for("foo"); // создаёт новый глобальный символ S2Symbol.for("foo"); // возвращает символ, созданный прежде34// Одинаковый глобальный символ, но не локальный5Symbol.for("bar") === Symbol.for("bar"); // true6Symbol("bar") === Symbol("bar"); // false
Symbol.iterator
Symbol.iterator
— известный символ, задающий итератор объекта, используемый по умолчанию.
Конструкция for..of
использует итераторы для перебора данных. В начале своего выполнения, for..of
автоматически вызывает Symbol.iterator()
для получения итератора и далее вызывает метод next()
до получения { done: true }
.
Это внутренняя механика JavaScript, так уж он работает.
Практика 👨💻👩💻
Написать класс Car
который будет содержать следующее
Приватные поля
- engine
- brand
- releaseYear
Публичные поля
- setBrand
- setEngine
- setReleaseYear
- getInfo - возвращает данные об автомобиле
1class Car{2}345const car = new Car('Lada');6console.log("brand", car.brand) // undefined;78car.brand = 'new brand'9console.log(car.getInfo()); // {brand: "Lada"}10car.setBrand('Samara')11console.log(car.getInfo()); // {brand: "Samara"}
Для приватных полей нужно использовать Symbol