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

В чем разница между примитивными и сложными типами данных в JavaScript?

1.0 Junior🔥 171 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Разница между примитивными и сложными типами данных в JavaScript

JavaScript использует два категории типов данных: примитивные и объектные (сложные). Это фундаментальное разделение влияет на то, как данные хранятся в памяти, как они передаются и сравниваются.

Примитивные типы

Примитивные типы — это неизменяемые (immutable) значения, которые хранятся в stack'е (стеке памяти).

Существует 7 примитивных типов:

  1. Number — числа (целые и дробные)
  2. String — текст
  3. Boolean — логические значения (true/false)
  4. Undefined — переменная объявлена, но не инициализирована
  5. Null — явно заданное отсутствие значения
  6. Symbol — уникальные идентификаторы (ES6)
  7. BigInt — очень большие целые числа (ES2020)
// Примеры примитивных типов
const num = 42;           // Number
const text = 'Hello';     // String
const flag = true;        // Boolean
let empty;                // undefined (не инициализирована)
const nothing = null;     // null (явное отсутствие)
const id = Symbol('uid'); // Symbol
const bigNum = 9007199254740991n; // BigInt

// Проверка типа
console.log(typeof 42);        // 'number'
console.log(typeof 'hello');   // 'string'
console.log(typeof true);      // 'boolean'
console.log(typeof undefined); // 'undefined'
console.log(typeof Symbol());  // 'symbol'
console.log(typeof 42n);       // 'bigint'

// Внимание: typeof null === 'object' — это ошибка JavaScript!
console.log(typeof null); // 'object' (исторический баг)

Ключевые характеристики примитивов:

  • Неизменяемость (Immutability): Нельзя изменить значение примитива
  • Сравнение по значению: 5 === 5 -> true
  • Хранение: Stack память (быстро)
  • Копирование: По значению (независимые копии)
// Неизменяемость примитивов
let str = 'hello';
str = str.toUpperCase(); // Не изменяет исходную строку!
// Создает НОВУЮ строку и присваивает ее переменной str
console.log(str); // 'HELLO'

// Сравнение примитивов
const a = 5;
const b = 5;
console.log(a === b); // true (сравнение по значению)

// Копирование примитивов
let x = 10;
let y = x;  // Копирует значение
y = 20;
console.log(x); // 10 (x не изменился)
console.log(y); // 20

Сложные типы (Объекты)

Сложные типы (Object types) — это изменяемые структуры данных, которые хранятся в heap'е (куче памяти). Содержат ссылку на адрес в памяти.

Основные сложные типы:

  1. Object — базовый объект {}
  2. Array — массив []
  3. Function — функции
  4. Date — дата и время
  5. RegExp — регулярные выражения
  6. Map, Set, WeakMap, WeakSet — коллекции
// Примеры сложных типов
const obj = { name: 'John', age: 30 };     // Object
const arr = [1, 2, 3];                     // Array
const func = () => console.log('hi');      // Function
const date = new Date();                   // Date
const regex = /[a-z]+/g;                   // RegExp
const map = new Map();                     // Map
const set = new Set([1, 2, 3]);            // Set

// Проверка типа
console.log(typeof {});        // 'object'
console.log(typeof []);        // 'object' (массив — это объект!)
console.log(typeof function(){}); // 'function'
console.log(typeof new Date()); // 'object'

Ключевые характеристики объектов:

  • Изменяемость (Mutability): Можно добавлять, удалять, менять свойства
  • Сравнение по ссылке: Два разных объекта {} === {} -> false
  • Хранение: Heap память (медленнее, но больше места)
  • Копирование: По ссылке (оба указывают на один адрес)
// Изменяемость объектов
const person = { name: 'John', age: 30 };
person.age = 31;  // Можно изменять свойства
person.city = 'NYC'; // Можно добавлять новые
console.log(person); // { name: 'John', age: 31, city: 'NYC' }

// Сравнение объектов (по ссылке!)
const obj1 = { name: 'John' };
const obj2 = { name: 'John' };
console.log(obj1 === obj2); // false (разные объекты в памяти)
console.log(obj1 === obj1); // true (одна и та же ссылка)

// Копирование объектов (по ссылке)
const original = { count: 0 };
const copy = original;  // copy указывает на ТОТ ЖЕ объект
copy.count = 5;
console.log(original.count); // 5 (изменился и оригинал!)

// Правильное копирование объекта
const deepCopy = { ...original }; // Поверхностная копия
deepCopy.count = 10;
console.log(original.count); // 5 (оригинал не изменился)

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

ПараметрПримитивныеСложные
ТипыNumber, String, Boolean, null, undefined, Symbol, BigIntObject, Array, Function, Date, RegExp, Map, Set
ИзменяемостьНеизменяемыеИзменяемые
СравнениеПо значениюПо ссылке (адресу в памяти)
ХранениеStackHeap
КопированиеПо значениюПо ссылке
СкоростьБыстроМедленнее
Проверка типаtypeof работаетtypeof возвращает 'object'

Практические примеры

Пример 1: Изменяемость строк vs массивов

// Примитив (String) — не изменяем
let message = 'hello';
message[0] = 'H'; // Попытка изменить
console.log(message); // 'hello' (не изменилась!)

// Объект (Array) — изменяем
let arr = ['h', 'e', 'l', 'l', 'o'];
arr[0] = 'H'; // Изменяем
console.log(arr); // ['H', 'e', 'l', 'l', 'o']

Пример 2: Передача аргументов

function changePrimitive(num) {
  num = 100;  // Изменяет только локальную переменную
}

let x = 5;
changePrimitive(x);
console.log(x); // 5 (не изменился)

// ---

function changeObject(obj) {
  obj.name = 'Modified'; // Изменяет объект в памяти
}

const person = { name: 'John' };
changeObject(person);
console.log(person.name); // 'Modified' (изменился!)

Пример 3: Сравнение значений

// Примитивы — сравнение по значению
console.log(5 === 5);         // true
console.log('hello' === 'hello'); // true

// Объекты — сравнение по ссылке
console.log([1,2] === [1,2]);  // false (разные массивы в памяти)
console.log({} === {});        // false (разные объекты)

// Для сравнения объектов нужна помощь
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
console.log(JSON.stringify(arr1) === JSON.stringify(arr2)); // true

Важные заметки

  1. Упаковка примитивов (Boxing) — JavaScript автоматически преобразует примитивы в объекты когда нужно
const str = 'hello';
console.log(str.length); // 5
// JS временно преобразует 'hello' (примитив) в String('hello') (объект)
console.log(str.toUpperCase()); // 'HELLO'
  1. const vs let/var — не путай с неизменяемостью
const arr = [1, 2, 3];
arr.push(4); // Можно! const защищает переменную, не значение
console.log(arr); // [1, 2, 3, 4]

arr = [5, 6]; // Ошибка! Нельзя переassign const

Вывод

Примитивные типы — это простые, неизменяемые значения, которые сравниваются по значению и хранятся в stack.

Сложные типы — это объекты, которые изменяемы, сравниваются по ссылке и хранятся в heap.

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