Ответ
Примитивы — это простые, неизменяемые (immutable) значения, хранящиеся по значению. Объекты — это сложные, изменяемые (mutable) структуры, хранящиеся по ссылке.
Список примитивов в JS: string, number, bigint, boolean, undefined, null, symbol.
Основные различия:
| Характеристика | Примитивы | Объекты |
|---|---|---|
| Мутабельность | Неизменяемы. Любая операция создаёт новое значение. | Изменяемы. Свойства можно добавлять, изменять, удалять. |
| Способ хранения и присваивания | По значению. При присваивании копируется само значение. | По ссылке. При присваивании копируется ссылка на один и тот же объект в памяти. |
| Сравнение | Сравниваются по значению. | Сравниваются по ссылке (два разных объекта с одинаковыми свойствами не равны). |
| Наличие свойств/методов | Нет. Но при обращении как к объекту JS временно оборачивает их в "обёртку" (String, Number). | Есть. Могут содержать свойства и методы. |
Пример, демонстрирующий разницу в присваивании и сравнении:
// ПРИМИТИВЫ (передача по значению)
let a = 10;
let b = a; // Создаётся КОПИЯ значения 10
b = 20;
console.log(a); // 10 (оригинал не изменился)
console.log(a === 10); // true (сравнение по значению)
// ОБЪЕКТЫ (передача по ссылке)
let obj1 = { value: 10 };
let obj2 = obj1; // Копируется ССЫЛКА на один объект в памяти
obj2.value = 20;
console.log(obj1.value); // 20 (изменился общий объект)
console.log(obj1 === obj2); // true (это одна и та же ссылка)
let obj3 = { value: 10 };
console.log(obj1 === obj3); // false (разные объекты, даже с одинаковыми данными)
Важный нюанс — "обёртки" для примитивов:
let str = "hello"; // Примитив string
console.log(str.toUpperCase()); // "HELLO"
// На момент вызова метода JS делает временный объект new String(str),
// вызывает метод, а затем удаляет его.
Практический вывод: При работе с объектами для создания настоящей независимой копии используйте методы глубокого клонирования (JSON.parse(JSON.stringify(obj)), structuredClone(), _.cloneDeep()).