Какие типы структур данных используются в 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, и позволяет вручную реализовывать структуры, отсутствующие в стандартной библиотеке, с помощью классов и замыканий.