Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Методы и свойства объекта Symbol в JavaScript
Symbol — это примитивный тип данных, появившийся в ES6, который представляет собой уникальный и неизменяемый идентификатор. Объект Symbol предоставляет несколько полезных статических методов и свойств для работы с символами.
Основные методы Symbol
1. Symbol.for(key)
Ищет символ в глобальном реестре символов по ключу. Если символ существует — возвращает его, если нет — создает новый.
const globalSym1 = Symbol.for('app.unique');
const globalSym2 = Symbol.for('app.unique');
console.log(globalSym1 === globalSym2); // true
- Используется для создания глобально доступных символов.
- Ключом может быть строка (приводится к строке, если передано иное).
2. Symbol.keyFor(sym)
Получает строковый ключ символа из глобального реестра.
const globalSym = Symbol.for('shared');
console.log(Symbol.keyFor(globalSym)); // 'shared'
const localSym = Symbol('local');
console.log(Symbol.keyFor(localSym)); // undefined
- Возвращает
undefined, если символ не зарегистрирован глобально.
3. Symbol.toStringTag
Встроенный символ, определяющий строковое представление объекта при вызове Object.prototype.toString.
const myObj = {
[Symbol.toStringTag]: 'MyCustomObject'
};
console.log(Object.prototype.toString.call(myObj)); // [object MyCustomObject]
- Используется для кастомизации вывода типа в консоли и дебаггинге.
Встроенные символы (well-known symbols)
Это предопределенные символы, которые управляют внутренним поведением объектов (методами движка):
Symbol.iterator
Определяет итератор по умолчанию для объекта. Позволяет использовать for...of и spread-оператор.
const iterableObj = {
*[Symbol.iterator]() {
yield 1;
yield 2;
yield 3;
}
};
console.log([...iterableObj]); // [1, 2, 3]
Symbol.asyncIterator
Определяет асинхронный итератор для использования с for await...of (ES2018).
const asyncIterable = {
async *[Symbol.asyncIterator]() {
yield await Promise.resolve(1);
yield await Promise.resolve(2);
}
};
Symbol.hasInstance
Определяет логику работы оператора instanceof.
class MyArray {
static [Symbol.hasInstance](instance) {
return Array.isArray(instance);
}
}
console.log([] instanceof MyArray); // true
Symbol.toPrimitive
Позволяет контролировать преобразование объекта к примитиву.
const obj = {
[Symbol.toPrimitive](hint) {
if (hint === 'number') return 42;
if (hint === 'string') return 'строка';
return 'дефолт';
}
};
console.log(+obj); // 42
console.log(`${obj}`); // 'строка'
Symbol.isConcatSpreadable
Определяет, будет ли объект "разворачиваться" при использовании Array.prototype.concat.
const arr = [1, 2];
arr[Symbol.isConcatSpreadable] = false;
console.log([].concat(arr)); // [[1, 2]] — массив не развернулся
Symbol.match, Symbol.replace, Symbol.search, Symbol.split
Позволяют объектам выступать в качестве регулярных выражений в строковых методах.
const customMatcher = {
[Symbol.match](string) {
return string.includes('custom') ? ['found'] : null;
}
};
console.log('some custom string'.match(customMatcher)); // ['found']
Symbol.species
Определяет конструктор, который будет использоваться при создании производных объектов (например, при вызове map, filter на массиве).
class MyArray extends Array {
static get [Symbol.species]() {
return Array; // Производные объекты будут Array, а не MyArray
}
}
const myArr = new MyArray(1, 2, 3);
const mapped = myArr.map(x => x * 2);
console.log(mapped instanceof MyArray); // false
console.log(mapped instanceof Array); // true
Symbol.unscopables
Указывает, какие свойства не должны быть доступны в with-блоке (исторический метод, сейчас редко используется).
const obj = {
a: 1,
b: 2,
[Symbol.unscopables]: { b: true }
};
with(obj) {
console.log(a); // 1
console.log(b); // ReferenceError
}
Практическое применение символов
- Создание уникальных ключей для свойств объектов, чтобы избежать коллизий:
const privateData = Symbol('userData');
class User {
constructor(name) {
this[privateData] = { name };
}
getName() {
return this[privateData].name;
}
}
- Определение метаданных объектов без риска перезаписи.
- Реализация протоколов итерации, преобразования типов.
- Создание "скрытых" свойств, которые не видны в
for...in,Object.keys(), но доступны черезObject.getOwnPropertySymbols()илиReflect.ownKeys().
Важно: символы не являются полностью приватными — их можно получить через API отражения, но они обеспечивают уровень защиты от случайных конфликтов имен в кодовой базе и сторонних библиотеках. Они стали фундаментом для многих продвинутых возможностей JavaScript, включая итераторы, асинхронные итераторы и кастомизацию встроенных операторов.