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

Для чего нужно деление на примитивные типы и объекты?

1.3 Junior🔥 121 комментариев
#JavaScript Core

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

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

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

Деление на примитивные типы и объекты

Краткий ответ

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

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

Это 7 типов значений, которые хранятся непосредственно в памяти:

  1. Number42, 3.14, Infinity, NaN
  2. String"Hello", 'World', backticks
  3. Booleantrue, false
  4. Undefinedundefined
  5. Nullnull
  6. SymbolSymbol('id')
  7. BigInt123n, 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 нужны новые объекты, не мутации)
  • Помните: даже строки и числа могут вызывать методы благодаря упаковке