Итерация объектов с Symbol-ключами в JavaScript

Обновлено:

Я уже более 10 лет работаю с JS и сегодня открыл для себя кое-что новое.

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

Symbol-ключи встречаются в реальных проектах не так часто, но когда встречаются — например, при работе с метаданными, внутренними флагами библиотек (React, Redux), или при создании «приватных» свойств — важно знать, как с ними работать.

Как итерировать объект с Symbol-ключами

Стандартные методы Object.keys() и Object.entries() не возвращают символьные ключи. Для работы с символами можно использовать:

  1. Object.getOwnPropertySymbols() — возвращает массив всех символьных ключей объекта.
  2. Reflect.ownKeys() — возвращает массив всех ключей объекта, включая строки и символы.

Пример итерации по объекту с символьными ключами

const symbolKey = Symbol('uniqueKey');
const a = { [symbolKey]: 123, regularKey: 'value' };

// 1. Использование Object.getOwnPropertySymbols()
const symbolKeys = Object.getOwnPropertySymbols(a);
symbolKeys.forEach((key) => {
  console.log('Symbol key:', key, 'Value:', a[key]);
});

// 2. Использование Reflect.ownKeys()
const allKeys = Reflect.ownKeys(a);
allKeys.forEach((key) => {
  if (typeof key === 'symbol') {
    console.log('Symbol key:', key, 'Value:', a[key]);
  } else {
    console.log('Regular key:', key, 'Value:', a[key]);
  }
});

Вывод

  1. Object.getOwnPropertySymbols():

    Symbol key: Symbol(uniqueKey) Value: 123
    
  2. Reflect.ownKeys():

    Regular key: regularKey Value: value
    Symbol key: Symbol(uniqueKey) Value: 123
    

Почему for...in не подходит

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

Почему Object.entries() не подходит

Object.entries() также не возвращает символьные ключи, поэтому он не подходит для таких объектов.

Итог

Для итерации по объекту с символьными ключами используйте:

  • Object.getOwnPropertySymbols(), если нужны только символьные ключи.
  • Reflect.ownKeys(), если нужны все ключи (строки и символы).