Типы данных
В JavaScript 8 типов данных: 7 примитивных (string, number, boolean, null, undefined, symbol, bigint) и 1 ссылочный (object).
Зачем нужно
Понимание типов данных — фундамент. От типа зависит, какие операции доступны, как работает сравнение, как данные хранятся в памяти и передаются в функции.
Где используется
Каждая переменная в JavaScript имеет тип. Типы определяют поведение операторов, проверки условий, работу с API и структурами данных.
Предпосылки
Примитивные типы
7 примитивов
// 1. string — строки
const name = 'Алиса';
const greeting = "Привет";
const template = `Привет, ${name}!`;
// 2. number — числа (целые и дробные)
const age = 25;
const price = 19.99;
const negative = -10;
// 3. boolean — логический
const isActive = true;
const isDeleted = false;
// 4. null — явное «ничего»
const empty = null;
// 5. undefined — значение не присвоено
let notAssigned;
console.log(notAssigned); // undefined
// 6. symbol — уникальный идентификатор
const id = Symbol('id');
// 7. bigint — большие целые числа
const huge = 9007199254740991n;
Свойства примитивов
// Примитивы неизменяемы (immutable)
let str = 'hello';
str[0] = 'H'; // Не сработает
console.log(str); // 'hello'
// Примитивы сравниваются по значению
console.log(5 === 5); // true
console.log('abc' === 'abc'); // true
// Примитивы копируются по значению
let a = 10;
let b = a;
b = 20;
console.log(a); // 10 — не изменилось
Ссылочный тип (Object)
// Все непримитивные значения — объекты
const user = { name: 'Алиса', age: 25 };
const colors = ['red', 'green', 'blue'];
const greet = function { return 'Привет'; };
const now = new Date();
const pattern = /\d+/g;
// Объекты сравниваются по ссылке
const obj1 = { a: 1 };
const obj2 = { a: 1 };
console.log(obj1 === obj2); // false — разные ссылки!
const obj3 = obj1;
console.log(obj1 === obj3); // true — одна ссылка
// Объекты копируются по ссылке
const original = { x: 1 };
const copy = original;
copy.x = 999;
console.log(original.x); // 999 — изменился оригинал!
Оператор typeof
// typeof возвращает строку с названием типа
console.log(typeof 'hello'); // "string"
console.log(typeof 42); // "number"
console.log(typeof true); // "boolean"
console.log(typeof undefined); // "undefined"
console.log(typeof Symbol); // "symbol"
console.log(typeof 42n); // "bigint"
// Особые случаи (исторические баги)
console.log(typeof null); // "object" — баг с 1995 года!
console.log(typeof ); // "object"
console.log(typeof {}); // "object"
console.log(typeof function{}); // "function" — подтип объекта
console.log(typeof NaN); // "number" — NaN это число!
Проверка типов
Надёжные способы
// Проверка null
const value = null;
console.log(value === null); // true
// Проверка массива
console.log(Array.isArray([1, 2])); // true
console.log(Array.isArray('hello')); // false
// Проверка NaN
console.log(Number.isNaN(NaN)); // true
console.log(Number.isNaN('hello')); // false
// Проверка числа (не NaN, не Infinity)
console.log(Number.isFinite(42)); // true
console.log(Number.isFinite(Infinity)); // false
console.log(Number.isFinite('42')); // false
// Проверка целого числа
console.log(Number.isInteger(42)); // true
console.log(Number.isInteger(42.5)); // false
// Object.prototype.toString() — универсальный способ
function getType(value) {
return Object.prototype.toString().call(value).slice(8, -1);
}
console.log(getType(42)); // "Number"
console.log(getType('hello')); // "String"
console.log(getType(null)); // "Null"
console.log(getType()); // "Array"
console.log(getType({})); // "Object"
console.log(getType(new Date)); // "Date"
console.log(getType(/regex/)); // "RegExp"
instanceof
// instanceof проверяет цепочку прототипов
console.log( instanceof Array); // true
console.log({} instanceof Object); // true
console.log(new Date instanceof Date); // true
// Не работает для примитивов
console.log('hello' instanceof String); // false
console.log(42 instanceof Number); // false
Обёртки примитивов (Wrapper Objects)
// JS автоматически оборачивает примитивы в объекты для вызова методов
const str = 'hello';
console.log(str.toUpperCase()); // "HELLO"
// Под капотом: new String('hello').toUpperCase()
// Не создавай обёртки вручную!
const strObj = new String('hello');
console.log(typeof strObj); // "object" — не "string"!
console.log(strObj === 'hello'); // false
// Иерархия:
// String, Number, Boolean — обёртки
// Symbol, BigInt — НЕ имеют конструкторов с new
Схема типов
Типы JavaScript
├── Примитивные (по значению)
│ ├── string → "hello"
│ ├── number → 42, 3.14, NaN, Infinity
│ ├── boolean → true, false
│ ├── null → null
│ ├── undefined → undefined
│ ├── symbol → Symbol('id')
│ └── bigint → 42n
│
└── Ссылочные (по ссылке)
└── object
├── Object → { key: 'value' }
├── Array → [1, 2, 3]
├── Function → function {}
├── Date → new Date
├── RegExp → /pattern/
├── Map/Set → new Map
├── Error → new Error
└── ...
Частые ошибки
1. typeof null === "object"
// Всегда проверяй null явно
if (value !== null && typeof value === 'object') {
// Точно объект, не null
}
2. Сравнение объектов по значению
// Неправильно
console.log([1, 2] === [1, 2]); // false
// Правильно: сравнивай содержимое
JSON.stringify([1, 2]) === JSON.stringify([1, 2]); // true (простые случаи)
3. Мутация через ссылку
function addItem(arr) {
arr.push('new'); // Мутирует оригинал!
}
const list = ['a', 'b'];
addItem(list);
console.log(list); // ['a', 'b', 'new']
// Решение: создавай копию
function addItemSafe(arr) {
return [...arr, 'new'];
}
Практика
- Определи тип каждого значения:
42,"42",true,null,undefined, ``,{},Symbol,42n - Напиши функцию
isObject(value), которая возвращаетtrueтолько для объектов (не null, не массив) - Покажи разницу между копированием примитива и объекта
- Используй
Object.prototype.toString().callдля определения типа 5 разных значений
Связанные темы
Ресурсы
🎓 Источник: 👶 JavaScript для начинающих 4. Значения и типы
- 📅 2021-10-02 · YouTube
- Тезисы: значение vs тип — это две оси. Тип определяет набор операций. Динамическая типизация = тип привязан к значению, а не к идентификатору
⚡ Источник: Как одни фантазируют на тему типов, а другие верят · AsForJS
- 📅 2021-10-10 · YouTube
- Тезисы:
- Миф "примитивы передаются по значению, объекты — по ссылке" не соответствует спеке
- В ECMAScript есть
primitive valueиReference— ноReferenceэто про идентификатор, не про "передачу" - Когда вы пишете
let a = 5; let b = a— это не "копирование значения 5", а связывание идентификатора b с тем же значением 5 - Значения примитивов уникальны и неизменяемы — само число 5 одно на всех
⚡ Источник: Я тип простой - я говорю стихами · AsForJS
- 📅 2023-03-29 · YouTube
- Тезисы: обзор всех типов спецификации ECMAScript — Language Types vs Specification Types (Reference, Completion Record). typeof для null = "object" это исторический баг V0
⚡ Источник: Почему в JavaScript прибавить число к обьекту - это круто · AsForJS
- 📅 2023-05-18 · YouTube
- Тезисы:
{} + 1запускаетToPrimitive→[[ToPrimitive]]→Symbol.toPrimitive/valueOf/toString. Это не баг, а гибкость семантики