← Назад к вопросам
Для чего нужно деление на примитивные типы и объекты?
1.3 Junior🔥 121 комментариев
#JavaScript Core
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
Деление на примитивные типы и объекты
Краткий ответ
Это деление фундаментально для понимания JavaScript, потому что они работают по разным правилам: примитивы хранятся по значению, объекты — по ссылке. Это влияет на сравнение, передачу параметров, копирование и управление памятью.
Примитивные типы в JavaScript
Это 7 типов значений, которые хранятся непосредственно в памяти:
- Number —
42,3.14,Infinity,NaN - String —
"Hello",'World', backticks - Boolean —
true,false - Undefined —
undefined - Null —
null - Symbol —
Symbol('id') - BigInt —
123n,BigInt(456)
Всё остальное — это объекты: массы, функции, даты и т.д.
Примитивы: передача по значению
let a = 5;
let b = a; // Копируется ЗНАЧЕНИЕ
a = 10;
console.log(a); // 10
console.log(b); // 5 — не изменилось!
// В памяти:
// a: [10]
// b: [5]
Когда вы передаёте примитив, создаётся независимая копия.
Объекты: передача по ссылке
let obj1 = { name: 'Alice' };
let obj2 = obj1; // Копируется ССЫЛКА, не содержимое
obj1.name = 'Bob';
console.log(obj2.name); // 'Bob' — изменилось!
// В памяти:
// obj1: [адрес объекта]
// obj2: [адрес объекта] <- тот же адрес
// Объект: { name: 'Bob' } <- одна копия в памяти
Оба переменных указывают на один и тот же объект в памяти.
Как это влияет на функции
Примитивы в функциях
function changeValue(x) {
x = 100; // Меняем локальную копию
}
let num = 5;
changeValue(num);
console.log(num); // 5 — не изменилось
// Функция получила копию значения
Объекты в функциях
function changeObject(obj) {
obj.name = 'Changed'; // Меняем объект через ссылку
}
let user = { name: 'Alice' };
changeObject(user);
console.log(user.name); // 'Changed' — изменилось!
// Функция получила ссылку на тот же объект
Сравнение: примитивы vs объекты
Примитивы сравниваются по значению
console.log(5 === 5); // true
console.log('hello' === 'hello'); // true
console.log(true === true); // true
// Разные переменные, одно значение — равны
let a = 'test';
let b = 'test';
console.log(a === b); // true
Объекты сравниваются по ссылке
const obj1 = { x: 1 };
const obj2 = { x: 1 }; // Идентичное содержимое, но РАЗНЫЕ объекты
console.log(obj1 === obj2); // false!
console.log(obj1 === obj1); // true
// Массы тоже объекты
const arr1 = [1, 2, 3];
const arr2 = [1, 2, 3];
console.log(arr1 === arr2); // false
console.log(arr1 === arr1); // true
Копирование
Примитивы
let original = 42;
let copy = original; // Просто копируется значение
copy = 100;
console.log(original); // 42 — не изменился
Объекты — поверхностное копирование
const original = { name: 'Alice', age: 25 };
const copy = original; // НЕПРАВИЛЬНО — это не копия
copy.age = 30;
console.log(original.age); // 30 — изменилось!
// ПРАВИЛЬНО — поверхностное копирование
const shallowCopy = { ...original }; // Spread operator
shallowCopy.age = 30;
console.log(original.age); // 25 — не изменилось
Объекты — глубокое копирование
const original = {
name: 'Alice',
address: { city: 'Moscow', zip: 101000 }
};
const shallowCopy = { ...original };
shallowCopy.address.city = 'SPB';
console.log(original.address.city); // 'SPB' — вложенный объект скопирован по ссылке!
// Глубокое копирование
const deepCopy = JSON.parse(JSON.stringify(original));
deepCopy.address.city = 'SPB';
console.log(original.address.city); // 'Moscow' — оригинальный не изменился
Примитивы: неизменяемость (Immutability)
Примитивы неизменяемы — вы не можете менять их значение на месте:
let str = 'hello';
str[0] = 'H'; // Не работает
console.log(str); // 'hello' — не изменилось
// Единственный способ — переасигнировка
str = 'Hello'; // Новое значение, новое место в памяти
Объекты изменяемы — вы можете менять их содержимое:
const obj = { x: 1 };
obj.x = 2; // OK — меняем
obj.y = 3; // OK — добавляем
console.log(obj); // { x: 2, y: 3 }
Практические последствия
1. React и состояние
// НЕПРАВИЛЬНО — мутируете состояние напрямую
const [user, setUser] = useState({ name: 'Alice', age: 25 });
user.age = 26; // Мутация! React может не заметить
setUser(user); // Может не перерендерить
// ПРАВИЛЬНО — создаёте новый объект
setUser({ ...user, age: 26 });
2. Сравнения в условиях
// Для примитивов
if (user.role === 'admin') { }
// Для объектов — нужна глубокая проверка
const isEqual = JSON.stringify(obj1) === JSON.stringify(obj2);
// или
const isEqual = Object.keys(obj1).every(key => obj1[key] === obj2[key]);
3. Deconstructing
// Примитив
let a = 5;
let b = a;
let c = b; // Каждая переменная независима
// Объект
let obj = { x: 1 };
let ref1 = obj;
let ref2 = obj; // Все три указывают на один объект
Автоматическая упаковка (Boxing)
Это фишка JavaScript: примитивы временно "упаковываются" в объекты:
const str = 'hello';
console.log(str.length); // 5 — работает как объект
console.log(str.toUpperCase()); // 'HELLO' — как объект
// Но это временно
str.custom = 'value';
console.log(str.custom); // undefined — упаковка была временной
Когда какой тип использовать
// Примитивы — для простых данных
const id = 123;
const name = 'Alice';
const isActive = true;
const score = null;
// Объекты — для сложных структур
const user = {
id: 123,
name: 'Alice',
isActive: true,
tags: ['frontend', 'react']
};
// Функции — тоже объекты
const greet = (name) => `Hello, ${name}`;
console.log(typeof greet); // 'function' (но это объект!)
Вывод
- Примитивы (число, строка, булево, null, undefined, symbol, bigint) — хранятся по значению, неизменяемы
- Объекты (и функции, массы) — хранятся по ссылке, изменяемы
- Это влияет на:
- Копирование (примитив скопируется, объект нет)
- Сравнение (=== для примитивов работает, для объектов нет)
- Передачу в функции (примитив независим, объект влияет на оригинал)
- Управление состоянием (в React нужны новые объекты, не мутации)
- Помните: даже строки и числа могут вызывать методы благодаря упаковке