Символ в Javascript

Знакомство с символами: уникальный тип данных для свойств объектов

В JavaScript символы — это уникальные типы данных, которые можно использовать для создания идентификаторов свойств объекта. Символы не похожи на строки или числа, и их нельзя преобразовать в эти типы данных. Именно это делает их идеальными для создания идентификаторов.

Использование символов в Javascript

Когда вы создаете символ, вы можете дополнительно дать ему описание. Это полезно для отладки, но не обязательно.

Создать символ просто.

const mySymbol = Symbol();

Вы также можете создать символ с описанием.

const mySymbol = Symbol("my description");

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

const sym1 = Symbol("foo");
const sym2 = Symbol("foo");

// false
console.log(sym1 === sym2);

Что делает символы уникальными

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

const obj = {};
obj[mySymbol] = "bar";

// "bar"
console.log(obj[mySymbol]);

Вы можете использовать символы в качестве ключей для свойств объекта, но не можете использовать их в качестве имен свойств (ключей) в JSON.

const sym = Symbol("foo");
const obj = { [sym]: "bar" };

// {}
console.log(JSON.stringify(obj));

Символы не являются перечисляемыми, поэтому они не будут отображаться, когда вы используете цикл for-in для объекта.

const obj = {};
obj[Symbol("a")] = "a";
obj[Symbol("b")] = "b";

for (var key in obj) {
  // undefined
  console.log(key);
}

Вы можете использовать Object.getOwnPropertySymbols, чтобы получить массив всех символов объекта.

const obj = {};
obj[Symbol("a")] = "a";
obj[Symbol("b")] = "b";

const symbols = Object.getOwnPropertySymbols(obj);

// [Symbol(a), Symbol(b)]
console.log(symbols);

Использование символа в качестве итератора

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

const arr = [1, 2, 3];
const it = arr[Symbol.iterator]();

// { value: 1, done: false }
console.log(it.next());

// { value: 2, done: false }
console.log(it.next());

// { value: 3, done: false }
console.log(it.next()); 

// { value: undefined, done: true }
console.log(it.next());

Более реальный пример

Вы можете создавать свои собственные символы, но нет никакой гарантии, что они будут уникальными. Если вам нужен уникальный символ, вы должны использовать Symbol().

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

const person = {
  name: "John Doe"
};
const birthYear = Symbol("birth year");
person[birthYear] = "1955";

for (var key in person) {
  // name
  console.log(key); 
}

// 1955
console.log(person[birthYear]);