Какие типы данных есть в JavaScript? Примитивы и объекты

Классический стартовый вопрос: «Перечислите типы данных в JavaScript».

Примитив — простое неизменяемое значение, которое хранится и копируется по значению. Объект — составная структура, которая хранится и передаётся по ссылке.

Ответ собеседнику

В JavaScript семь примитивных типов: number, string, boolean, null, undefined, symbol, bigint. Всё остальное — это object (включая массивы и функции). Главная мысль, которую ждёт собеседник: примитивы копируются по значению, объекты — по ссылке.

Примитивы копируются по значению

Когда вы присваиваете примитив другой переменной, копируется само значение. Изменение копии не трогает оригинал.

let a = 10;
let b = a;   // скопировалось значение 10
b = 20;

console.log(a); // не изменилось
console.log(b);

Вывод:

10
20

Объекты копируются по ссылке

А вот переменная с объектом хранит не сам объект, а ссылку на него в памяти. Присваивание копирует ссылку — обе переменные смотрят на один и тот же объект.

const obj1 = { count: 1 };
const obj2 = obj1;   // скопировалась ссылка, не объект
obj2.count = 99;

console.log(obj1.count); // изменился и obj1!
console.log(obj1 === obj2);

Вывод:

99
true

Именно поэтому массивы и объекты, переданные в функцию, могут «неожиданно» меняться снаружи — функция получила ссылку, а не копию.

Проверка типа

Тип примитива узнают через typeof. Тонкость: массив — это тоже объект, поэтому для массивов используют Array.isArray.

console.log(typeof 42);
console.log(typeof "hi");
console.log(typeof true);
console.log(typeof undefined);
console.log(typeof {});
console.log(typeof []);
console.log(Array.isArray([]));

Вывод:

number
string
boolean
undefined
object
object
true

Памятка

КатегорияТипыКак копируется
Примитивыnumber, string, boolean, null, undefined, symbol, bigintпо значению
Объектыobject, array, function, Date, Map, Set...по ссылке

Тонкости, на которых ловят

Несколько деталей, которые отличают уверенный ответ. Во-первых, примитивы неизменяемы: когда вы делаете str.toUpperCase(), исходная строка не меняется — создаётся новая. Во-вторых, у примитивов как будто есть методы ("hi".length), хотя сами они не объекты: движок на момент обращения временно «оборачивает» примитив в объект-обёртку (String, Number), а затем выбрасывает её. В-третьих, function и массив — это специальные объекты, поэтому typeof для них даёт "function" и "object" соответственно. Если спросят «сколько всего типов возвращает typeof?» — их восемь: семь для примитивов (где null даёт "object") плюс "function" и "object".

Итог

  • Семь примитивов; всё остальное — объекты.
  • Примитивы копируются по значению, объекты — по ссылке.
  • Это объясняет, почему мутация объекта видна во всех переменных, ссылающихся на него.
Проверьте себя
1. Сколько примитивных типов в современном JavaScript?
A5
B6
C7
D9
2. Что выведет код: const a = {x:1}; const b = a; b.x = 5; console.log(a.x);?
A1
B5
Cundefined
DОшибку
3. Что вернёт typeof [] ?
A"array"
B"object"
C"list"
D"undefined"
Поддержать проект