Ответ
Примитивы — это простые, неизменяемые (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()).
Ответ 18+ 🔞
А, ну вот, опять про эти ваши примитивы и объекты, блядь. Сидишь такой, думаешь — ну что тут сложного? Ан нет, народ путается, как слепой кот в сортире, ёпта.
Смотри сюда, я тебе на пальцах, только без пальцев, а то их тоже можно за объекты принять, блядь.
Примитивы — это как вот эти, ну, базовые кирпичики, простые и тупые. Взять, положить, скопировать — и всё, блядь. Самые главные из них: string (буквы), number (циферки), bigint (циферки, но овердохуища), boolean (правда или ложь, как в жизни), undefined (хуй знает что), null (ничего, но специально) и symbol (какой-то магический знак, нахуй не нужный пока).
Объекты — это уже не кирпич, а целый дом, блядь, со всеми потрохами. Массив, функция, твой собственный { name: 'Вася' } — всё это объекты, хитрая жопа.
А теперь в чём разница, блядь?
| Что сравниваем | Примитивы | Объекты |
|---|---|---|
| Можно ли поменять? | Нихуя! Они как святой — неизменны. Сделал операцию — получил новое значение, старое на помойку. | Да запросто! Живой, как тёща. Добавляй свойства, меняй, удаляй — он всё стерпит, манда с ушами. |
| Как хранятся и копируются? | По значению. Скопировал a в b — получил два одинаковых, но РАЗНЫХ кирпича. |
По ссылке. Скопировал obj1 в obj2 — получил две бумажки с адресом одного и того же дома. Пнул дом через obj2 — в obj1 тоже дыра будет, пиздец. |
| Как сравнивать? | По значению. Два яблока — они и в Африке яблоки, если одинаковые. | По ссылке. Два одинаковых дома на разных улицах — это РАЗНЫЕ дома, блядь! Сравниваешь адреса, а не стены. |
| Есть ли свойства и методы? | Вообще-то нет. Но JS, такой добрый дядя, иногда подкидывает им временную "обёртку", чтобы метод вызвать, а потом её нахуй стирает. Красота! | Конечно есть, это их фишка! Сидят там, как пассажиры в автобусе. |
Ну и пример, чтобы совсем мозг не взорвался:
// ПРИМИТИВЫ (живут своей жизнью)
let a = 10; // Кирпич с цифрой 10
let b = a; // Сделали ТОЧНУЮ КОПИЮ кирпича. Теперь их два.
b = 20; // Второй кирпич перекрасили в 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"; // Просто строка, примитив, тупой как пробка
console.log(str.toUpperCase()); // "HELLO"
// А как так? У примитива нет методов!
// А JS в этот момент делает так: "Опа, надо метод вызвать. Ща, я его в костюмчик нарядный заверну!"
// Создаётся временный объект `new String(str)`, у него есть метод, он вызывается,
// результат дали, а костюмчик — нахуй выкинули. Волшебство, ёпта!
Практический вывод, который в душу бьёт: Работаешь с объектами — не будь мудаком, как тот Герасим. Хочешь настоящую копию, чтобы её менять отдельно? Не просто присваивай, а клонируй, блядь, глубоко! JSON.parse(JSON.stringify(obj)), structuredClone() или там библиотеки всякие. А то потом будешь метаться и спрашивать: "Кто, сука, мне значение поменял?!"