Какие типы структур данных используются в JavaScript?

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

🔹 1. Примитивные типы (Primitive Types)

Хотя они не являются структурами данных в классическом смысле, важно понимать их роль, так как они лежат в основе многих структур:

  • Number: целые и числа с плавающей точкой.

  • String: последовательность символов (иммутабельна).

  • Boolean: true или false.

  • Undefined: переменная объявлена, но не имеет значения.

  • Null: «пустое» или «неизвестное» значение.

  • Symbol: уникальные и неизменяемые идентификаторы.

  • BigInt: целые числа произвольной длины.

Примитивы не являются объектами и хранятся по значению, а не по ссылке.

🔹 2. Объекты как структуры данных

2.1. Object

  • Является хэш-таблицей: ключ-значение.

  • Ключами могут быть строки или символы (Symbol).

  • Порядок свойств не гарантируется (за исключением некоторых правил с ES2015).

Пример:

const user = {
name: "Alice",
age: 30
};

2.2. Array

  • Упорядоченная коллекция данных.

  • Доступ по индексу.

  • Можно хранить значения любого типа.

  • Под капотом реализован как объект, оптимизированный под числовые индексы.

Пример:

const list = [1, 2, 3, 4];

🔹 3. Специализированные структуры данных (ES6+)

3.1. Set

  • Хранит уникальные значения любого типа.

  • Итерация в порядке вставки.

  • Полезен для фильтрации дубликатов и быстрых проверок наличия.

const unique = new Set(\[1, 2, 2, 3\]); // Set(3) {1, 2, 3}

3.2. WeakSet

  • Хранит только объекты.

  • Не предотвращает сборку мусора.

  • Нельзя перебрать (for...of, .size не работают).

  • Используется, когда важно избегать утечек памяти.

const weak = new WeakSet();
const obj = {};
weak.add(obj);

3.3. Map

  • Коллекция пар ключ-значение, где ключами могут быть любые типы (в отличие от Object).

  • Итерация в порядке вставки.

  • Подходит для создания словарей, кэширования и ассоциативных массивов.

const map = new Map();
map.set('name', 'Alice');
map.set({}, 123);

3.4. WeakMap

  • Ключи только объекты.

  • Без итерации, не имеет .size.

  • Применяется для хранения приватных данных объектов или кэшей без риска утечки памяти.

🔹 4. Очереди и стеки (реализуются вручную)

4.1. Стек (Stack)

LIFO (последним пришёл — первым ушёл).

const stack = \[\];
stack.push(1);
stack.push(2);
stack.pop(); // 2

4.2. Очередь (Queue)

FIFO (первым пришёл — первым ушёл).

const queue = \[\];
queue.push(1);
queue.push(2);
queue.shift(); // 1

Для высокопроизводительных очередей лучше использовать связные списки.

🔹 5. Связанные списки, деревья, графы и т.п. (реализуются вручную)

JavaScript не предоставляет встроенных структур, таких как:

  • Связанный список (Linked List);

  • Дерево (Tree);

  • Граф (Graph);

  • Куча (Heap);

  • Хэш-таблица (встроенно реализована в Object и Map);

  • Дек (Deque).

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

Пример — простой узел связанного списка:

class Node {
constructor(value) {
this.value = value;
this.next = null;
}
}

🔹 6. Итерабельные структуры и генераторы

Любой объект, реализующий метод Symbol.iterator, считается итерабельным и может использоваться в for...of.

Пример:

const iterable = {
\*\[Symbol.iterator\]() {
yield 1;
yield 2;
yield 3;
}
};

Также стоит учитывать Generator как средство создания ленивых коллекций данных.

🔹 7. Typed Arrays

Для работы с бинарными данными:

- ArrayBuffer, DataView;     
- Int8Array, Uint8Array, Float32Array и т.п.     

Используются в WebGL, медиа, криптографии, сетевых API.

const buffer = new ArrayBuffer(16);
const intView = new Int32Array(buffer);
intView\[0\] = 42;

🔹 8. Proxy и Reflect

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

const target = {};
const proxy = new Proxy(target, {
get(obj, prop) {
return prop in obj ? obj\[prop\] : 'not found';
}
});

🔹 9. JSON и сериализуемые структуры

Хотя JSON — формат обмена данными, объекты, которые сериализуются с помощью JSON.stringify, тоже являются формой представления данных. Сюда относятся:

  • Простые объекты { key: value };

  • Массивы;

  • Примитивы.

🔹 10. DOM-структуры (специфично для браузера)

  • NodeList, HTMLCollection, DocumentFragment — это коллекции, похожие на массивы, используемые в DOM.

  • FormData, FileList, Blob, Headers, URLSearchParams — специфичные структуры для веб-разработки.

Сравнение популярных структур данных по времени доступа

Структура Поиск Вставка Удаление
Array (по индексу) O(1) O(n) (в начало) O(n)
--- --- --- ---
Set O(1) O(1) O(1)
--- --- --- ---
Map O(1) O(1) O(1)
--- --- --- ---
Object O(1) O(1) O(1)
--- --- --- ---
WeakMap/WeakSet O(1) O(1) O(1)
--- --- --- ---
Очередь/Стек O(1) O(1) O(1)
--- --- --- ---

Эти значения могут варьироваться в зависимости от реализации движка (V8, SpiderMonkey, Chakra и т.д.), но в общем случае Map и Set показывают лучшую предсказуемую производительность по сравнению с Object и Array при больших объёмах данных.

Таким образом, JavaScript поддерживает широкий спектр встроенных и пользовательских структур данных, от простых массивов и объектов до более сложных — Map, Set, TypedArray, и позволяет вручную реализовывать структуры, отсутствующие в стандартной библиотеке, с помощью классов и замыканий.