← Назад к вопросам

Какие типы данных в JavaScript относятся к сложным?

1.0 Junior🔥 182 комментариев
#Node.js и JavaScript

Комментарии (2)

🐱
claude-haiku-4.5PrepBro AI29 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Какие типы данных в JavaScript относятся к сложным?

В JavaScript существует разделение между примитивными и сложными (ссылочными) типами данных. Это важное различие влияет на то, как данные хранятся, копируются и сравниваются.

Краткое резюме

Примитивные типы (6):

  • String
  • Number
  • Boolean
  • Undefined
  • Null
  • Symbol (BigInt в новых версиях)

Сложные типы (ссылочные):

  • Object
  • Array
  • Function
  • Date
  • RegExp
  • Map, Set, WeakMap, WeakSet

1. Object (Объект)

Object — базовый тип, из которого наследуются все остальные сложные типы:

// Объект
const user = {
  id: 1,
  name: 'John',
  email: 'john@example.com'
};

// При присваивании копируется ссылка, не данные
const user2 = user;
user2.name = 'Jane';
console.log(user.name); // "Jane" — оба указывают на один объект

// Поверхностная копия
const user3 = { ...user }; // или Object.assign({}, user)
user3.name = 'Bob';
console.log(user.name); // "Jane" — теперь отдельные объекты

// Глубокая копия
const user4 = JSON.parse(JSON.stringify(user));
const user5 = structuredClone(user); // Современный способ

Особенности:

  • Хранится по ссылке в памяти
  • Изменяемо (mutable)
  • Сравнение по ссылке, не по значению

2. Array (Массив)

Array — специализированный объект с индексированным доступом:

// Массив — это объект с числовыми ключами
const arr = [1, 2, 3];
console.log(typeof arr); // "object"
console.log(arr instanceof Array); // true

// Это эквивалентно
const obj = { 0: 1, 1: 2, 2: 3 };

// Тоже копируется по ссылке
const arr2 = arr;
arr2[0] = 99;
console.log(arr[0]); // 99

// Поверхностная копия
const arr3 = [...arr]; // или arr.slice(), arr.concat()
arr3[0] = 1;
console.log(arr[0]); // 99 — разные массивы

// Глубокая копия для вложенных массивов
const nested = [[1, 2], [3, 4]];
const copy = JSON.parse(JSON.stringify(nested));
const copy2 = structuredClone(nested);

Особенности:

  • Подтип Object
  • Индексированный доступ
  • Свойство .length
  • Полезные методы: map, filter, reduce, forEach и т.д.

3. Function (Функция)

Function — тоже объект, вызываемый код:

// Функции — объекты
function greet(name) {
  return `Hello, ${name}`;
}

console.log(typeof greet); // "function"
console.log(greet instanceof Function); // true

// Функции можно присваивать переменным
const sayHi = greet;
console.log(sayHi('John')); // "Hello, John"

// Функции имеют свойства
greet.description = 'Greeting function';
greet.version = '1.0';

// Стрелочные функции
const add = (a, b) => a + b;

// Конструктор функции
const multiply = new Function('a', 'b', 'return a * b');
console.log(multiply(3, 4)); // 12

// Функции как значения
const operations = {
  add: (a, b) => a + b,
  subtract: (a, b) => a - b,
  multiply: (a, b) => a * b
};

Особенности:

  • Первокласс (first-class citizen)
  • Может быть параметром
  • Может быть возвращаемым значением
  • Может иметь свойства

4. Date (Дата)

Date — объект для работы с датой и временем:

// Создание
const now = new Date();
const date1 = new Date('2024-03-29');
const date2 = new Date(2024, 2, 29); // месяц 0-indexed
const date3 = new Date(1711737600000); // timestamp в мс

// Методы
console.log(date1.getFullYear()); // 2024
console.log(date1.getMonth()); // 2 (март, 0-indexed)
console.log(date1.getDate()); // 29
console.log(date1.getTime()); // timestamp

// Манипуляция
const tomorrow = new Date();
tomorrow.setDate(tomorrow.getDate() + 1);

// Сравнение
const isAfter = date1 > date2;
const isSame = date1.getTime() === date2.getTime();

// Форматирование
console.log(now.toString()); // "Sat Mar 29 2024 ..."
console.log(now.toISOString()); // "2024-03-29T...Z"
console.log(now.toLocaleString('ru-RU')); // "29.03.2024, ..."

Особенности:

  • Мутабельна (изменяемая)
  • Хранит миллисекунды
  • Сравнение — трудное, используй .getTime()

5. RegExp (Регулярное выражение)

RegExp — объект для поиска и замены текста:

// Создание
const regex1 = /hello/i; // case-insensitive
const regex2 = new RegExp('hello', 'i');

// Методы
const text = 'Hello, World!';
console.log(regex1.test(text)); // true
console.log(regex1.exec(text)); // Match array или null

// String методы
console.log(text.match(regex1)); // ["Hello"]
console.log(text.replace(regex1, 'Hi')); // "Hi, World!"
console.log(text.split(/\s/)); // ["Hello,", "World!"]

// Сложное регулярное выражение
const email = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
console.log(email.test('john@example.com')); // true
console.log(email.test('invalid-email')); // false

Особенности:

  • Мутабельна (свойство lastIndex)
  • Флаги: g (global), i (ignoreCase), m (multiline), s, u, y
  • Производительность может быть критична

6. Map (Словарь)

Map — более надёжная альтернатива объекту для хранения пар ключ-значение:

// Создание
const map = new Map();
const map2 = new Map([['a', 1], ['b', 2]]);

// Методы
map.set('name', 'John');
map.set('age', 30);
map.set({}, 'object key'); // Даже объект может быть ключом

console.log(map.get('name')); // "John"
console.log(map.has('age')); // true
console.log(map.size); // 3

map.delete('age');
map.clear();

// Итерация
for (const [key, value] of map) {
  console.log(key, value);
}

map.forEach((value, key) => {
  console.log(key, value);
});

// Отличие от объекта
const obj = {};
const mapTest = new Map();

obj[{id: 1}] = 'object'; // ключ преобразуется в "[object Object]"
mapTest.set({id: 1}, 'map'); // ключ остаётся объектом

Преимущества перед Object:

  • Ключи могут быть любыми типами
  • Сохраняет порядок вставки
  • Есть .size вместо Object.keys().length
  • Лучше для большого количества пар
  • Итерация встроена (не нужен Object.entries)

7. Set (Множество)

Set — коллекция уникальных значений:

// Создание
const set = new Set();
const set2 = new Set([1, 2, 3, 1, 2]);
console.log(set2); // Set(3) { 1, 2, 3 }

// Методы
set.add(1);
set.add(2);
set.add(1); // Дубликат, не добавляется

console.log(set.has(1)); // true
console.log(set.size); // 2
set.delete(1);
set.clear();

// Удаление дубликатов из массива
const arr = [1, 2, 2, 3, 3, 3];
const unique = [...new Set(arr)];
console.log(unique); // [1, 2, 3]

// Сравнение объектов (внимание!)
const set3 = new Set();
set3.add({id: 1});
set3.add({id: 1});
console.log(set3.size); // 2 (разные объекты в памяти)

Используется для:

  • Удаления дубликатов
  • Проверки уникальности
  • Математические операции (объединение, пересечение)

8. WeakMap и WeakSet

WeakMap и WeakSet — версии с «слабыми» ссылками:

// WeakMap — ключи только объекты, могут быть GC
const weakMap = new WeakMap();
let obj = {id: 1};
weakMap.set(obj, 'value');

console.log(weakMap.get(obj)); // "value"
obj = null; // Объект может быть удалён из памяти

// WeakSet — для уникальных объектов
const weakSet = new WeakSet();
let obj2 = {id: 2};
weakSet.add(obj2);
console.log(weakSet.has(obj2)); // true
obj2 = null; // Объект может быть удалён

// Ограничения
// Нет .size, нельзя итерировать
// Используются для metadata, private данных

Сравнение примитивов и сложных типов

// Примитив — копируется значение
let a = 5;
let b = a;
b = 10;
console.log(a); // 5

// Сложный тип — копируется ссылка
let obj1 = {value: 5};
let obj2 = obj1;
obj2.value = 10;
console.log(obj1.value); // 10

// Сравнение
console.log(5 === 5); // true (значения)
console.log({a: 1} === {a: 1}); // false (разные ссылки)

const o = {a: 1};
console.log(o === o); // true (одна ссылка)

Таблица сравнения

ТипХранениеМутабельностьСравнениеИспользование
ObjectПо ссылкеДаПо ссылкеДанные
ArrayПо ссылкеДаПо ссылкеСписки
FunctionПо ссылкеНетПо ссылкеКод
DateПо ссылкеДаПо ссылкеВремя
RegExpПо ссылкеДаПо ссылкеПоиск
MapПо ссылкеДаПо ссылкеПары ключ-значение
SetПо ссылкеДаПо ссылкеУникальные значения
WeakMapПо ссылкеДаПо ссылкеMetadata
WeakSetПо ссылкеДаПо ссылкеТрекинг объектов

Практические советы

  • Помни о копировании — при работе со сложными типами
  • Используй structuredClone() для глубокой копии
  • Map вместо Object для произвольных ключей
  • WeakMap для private данных в классах
  • Set для уникальности элементов
  • Сравнивай правильно — {a:1} !== {a:1}, но они эквивалентны по значению