HTML / CSSJavaScriptNode jsПаттерны проектированияПрактические

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();
2
3const person = {
4 [NAME]: 'John'
5}
6
7person[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 = {};
2
3const r = Symbol('Roger');
4const s = Symbol('Syd');
5
6dog[r] = {
7 name: 'Roger',
8age: 6
9}
10
11dog[s] = {
12 name: 'Syd',
13 age: 5
14}
15
16console.log(Object.getOwnPropertySymbols(dog)) //[ Symbol(Roger), Symbol(Syd) ]

Методы

Symbol.for(key)

Метод Symbol.for(key) ищет ранее созданный разделяемый символ по заданному ключу и возвращает его, если он найден.

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

1Symbol.for("foo"); // создаёт новый глобальный символ S
2Symbol.for("foo"); // возвращает символ, созданный прежде
3
4// Одинаковый глобальный символ, но не локальный
5Symbol.for("bar") === Symbol.for("bar"); // true
6Symbol("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}
3
4
5const car = new Car('Lada');
6console.log("brand", car.brand) // undefined;
7
8car.brand = 'new brand'
9console.log(car.getInfo()); // {brand: "Lada"}
10car.setBrand('Samara')
11console.log(car.getInfo()); // {brand: "Samara"}

Для приватных полей нужно использовать Symbol

Hello