$ sudo teach IT

В JavaScript, как и в любом другом языке программирования, всё начинается с данных. Мы храним их, обрабатываем, преобразуем — и хотим, чтобы наш код работал предсказуемо. Однако не все данные одинаковы. Иногда вы складываете числа и получаете сумму, а иногда — склеенную строку. Почему так происходит?

В этом уроке мы разберём примитивные типы данных в JavaScript и научимся преобразовывать их из одного типа в другой. Это умение позволит вам:

  • Избегать неожиданных ошибок в коде.
  • Понимать, почему один и тот же оператор даёт разные результаты.
  • Работать с данными более гибко.

Что вы узнаете в рамках статьи

  • Какие бывают примитивные типы данных в JavaScript.
  • Как происходит явное и неявное преобразование типов.
  • Когда появляются значения NaN, null и undefined.
  • Какие значения считаются ложными (falsy).
  • Как избежать ошибок при работе с типами.

Ключевые термины

  • Примитивный тип — тип данных, который не является объектом и не имеет методов (например, string, number, boolean, null, undefined).
  • Явное преобразование — намеренное изменение типа данных с помощью функций (String(), Number(), Boolean()) или методов (.toString()).
  • Неявное преобразование — автоматическое изменение типа данных в процессе выполнения операции.
  • NaN — специальное значение "Not-a-Number", которое означает, что операция не вернула корректного числа.
  • Falsy значения — значения, которые в булевом контексте считаются ложными (false, 0, "", null, undefined, NaN).

1. Строки (Strings)

Строка — это упорядоченная последовательность символов, заключённая в:

  • одинарные кавычки ('Привет')
  • двойные кавычки ("Привет")
  • обратные кавычки (Привет — позволяют вставлять переменные и выражения через шаблонные строки).

Важно: В JavaScript строки неизменяемы. Это значит, что мы не можем изменить отдельный символ в строке по индексу, можно только создать новую строку.

Создание строки

const single = 'Привет';
const double = "Мир";
const template = `Привет, ${double}!`; // Интерполяция
console.log(template); // "Привет, Мир!"

Явное преобразование в строку

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

Метод .toString() Работает у чисел, булевых значений и некоторых других типов.

const num = 42;
console.log(num.toString()); // "42"

Функция String() Универсальный способ — принимает любое значение и возвращает строку.

const num = 42;
console.log(String(num)); // "42"

Разница: String() безопаснее, потому что null.toString() вызовет ошибку, а String(null) просто вернёт "null".

Неявное преобразование в строку

Это происходит автоматически, когда JavaScript ожидает строку, но видит другой тип данных.

Конкатенация с пустой строкой

const num = 42;
console.log("" + num); // "42"

Использование шаблонных строк

const age = 25;
console.log(`Мне ${age} лет`); // "Мне 25 лет"

При работе с оператором +

console.log("5" + 10); // "510" — число превратилось в строку

Примеры преобразования других типов в строку

console.log(String(true));       // "true"
console.log(String(false));      // "false"
console.log(String(null));       // "null"
console.log(String(undefined));  // "undefined"
console.log(String(NaN));        // "NaN"

2. Числа (Numbers)

В JavaScript все числа (целые и дробные) относятся к одному типу данных — number. Это значит, что числа с плавающей точкой (3.14) и целые числа (42) хранятся одинаково.

Особенности чисел в JavaScript:

  • Поддерживают положительные и отрицательные значения.
  • Есть специальные значения: Infinity, Infinity и NaN.
  • Используется формат IEEE 754, из-за чего могут возникать ошибки с точностью при работе с дробями:
console.log(0.1 + 0.2); // 0.30000000000000004

Явное преобразование в число

Это когда мы сами решаем, что хотим превратить строку или другой тип в число.

parseInt() — извлекает целое число из строки Читает строку слева направо, пока встречает цифры.

console.log(parseInt("42px"));  // 42
console.log(parseInt("101", 2)); // 5 (система счисления 2)

parseFloat() — извлекает дробное число из строки Позволяет сохранять десятичную часть.

console.log(parseFloat("42.5kg")); // 42.5

Number() — преобразует значение целиком Если в строке есть лишние символы — вернёт NaN.

console.log(Number("42"));     // 42
console.log(Number("42px"));   // NaN

Разница:

  • Number("42px") → NaN
  • parseInt("42px") → 42

Неявное преобразование в число

JavaScript автоматически превращает значения в числа в некоторых ситуациях.

Унарный +

console.log(+"12"); // 12
console.log(+true); // 1
console.log(+false); // 0

Математические операции При вычитании, умножении, делении и т.п. значения автоматически приводятся к числам.

console.log("10" - 5); // 5
console.log("6" * "2"); // 12
console.log("10" / "2"); // 5

NaN (Not-a-Number)

NaN — специальное значение, которое означает, что результат операции не является числом.

Причины появления NaN:

console.log(Number("abc"));    // NaN
console.log(0 / 0);            // NaN
console.log(parseInt("text")); // NaN

Особенности NaN:

console.log(NaN === NaN); // false
console.log(isNaN(NaN));  // true

Специальные числовые значения

Infinity — положительная бесконечность

console.log(1 / 0); // Infinity
  • Infinity — отрицательная бесконечность
console.log(-1 / 0); // -Infinity

3. Булевы значения (Booleans)

Булевый тип в JavaScript — это логический тип данных, который может принимать только два значения:

  • true — истина
  • false — ложь

Они используются для управления логикой программы: в условиях (if), циклах, при проверке совпадений и т.д.

Когда мы встречаем булевы значения

При выполнении сравнений:

console.log(5 > 3); // true
console.log(10 === 5); // false

В логических выражениях:

console.log(true && false); // false
console.log(true || false); // true

Явное преобразование в булево значение

Через функцию Boolean() Универсальный способ, подходит для любых типов данных.

console.log(Boolean(42)); // true
console.log(Boolean("")); // false
console.log(Boolean(null)); // false
console.log(Boolean("JavaScript")); // true

Через двойную инверсию !! Более короткий и популярный способ среди разработчиков.

console.log(!!42);  // true
console.log(!!"");  // false
console.log(!!null); // false

Falsy и Truthy значения

В JavaScript любое значение в булевом контексте (например, в if) становится либо true, либо false.

Falsy (ложные) значения:

  • false
  • 0 и 0
  • "" (пустая строка)
  • null
  • undefined
  • NaN

Все остальные значения считаются truthy (истинными), включая:

  • "0" (строка с нулём)
  • " " (строка с пробелом)
  • [] (пустой массив)
  • {} (пустой объект)
  • Infinity и Infinity

Пример:

if ("") {
  console.log("Это не выполнится");
} else {
  console.log("Пустая строка — ложное значение");
}

if ([]) {
  console.log("Пустой массив — истинное значение");
}

Неявное преобразование в булево значение

JavaScript автоматически преобразует значения в true или false в условиях, логических операциях и циклах.

В условиях if

if (42) {
  console.log("42 — это true в булевом контексте");
}

В логических операторах

console.log(!"");     // true — пустая строка становится false, затем инвертируется
console.log(!!"JS");  // true — непустая строка

Ловушки и неожиданные моменты

Пустой массив [] и пустой объект {} всегда truthy

console.log(Boolean([])); // true
console.log(Boolean({})); // true

Строка "false" — truthy

console.log(Boolean("false")); // true

0 и "0" ведут себя по-разному

console.log(Boolean(0));   // false
console.log(Boolean("0")); // true

4. null и undefined

В JavaScript есть два особых примитивных типа, которые обозначают "отсутствие значения", но используются в разных ситуациях:

  • null — намеренное отсутствие значения. Разработчик сам присваивает null, чтобы явно указать: "здесь ничего нет".
  • undefined — значение по умолчанию для переменных и свойств, которым не было присвоено значение.

Когда появляется undefined

Неинициализированная переменная

let a;
console.log(a); // undefined

Отсутствие аргумента при вызове функции

function greet(name) {
  console.log(name);
}
greet(); // undefined

Обращение к несуществующему свойству объекта

const user = { name: "Alice" };
console.log(user.age); // undefined

Нет оператора return в функции

function doNothing() {}
console.log(doNothing()); // undefined

Когда использовать null

Явное обнуление значения переменной

let data = { id: 1 };
data = null; // Теперь данные удалены

Начальное состояние переменной Если ожидается, что значение появится позже, можно задать null для ясности:

let selectedUser = null;
// Позже присвоим объект пользователя

Отсутствие результата Например, в базе данных поле может содержать null, чтобы показать, что данные отсутствуют.

Сравнение null и undefined

console.log(null == undefined);  // true — оба обозначают "нет значения"
console.log(null === undefined); // false — разные типы
console.log(typeof null);        // "object" (историческая ошибка JS)
console.log(typeof undefined);   // "undefined"

Запомни:

  • == (нестрогое сравнение) считает их равными.
  • === (строгое сравнение) — разными, так как это разные типы.

Преобразование в число

  • Number(null) → 0
  • Number(undefined) → NaN
console.log(Number(null));      // 0
console.log(Number(undefined)); // NaN

Преобразование в булево значение

  • Boolean(null) → false
  • Boolean(undefined) → false
console.log(Boolean(null));      // false
console.log(Boolean(undefined)); // false

Наиболее частые ошибки

Сравнение null и undefined с числами

console.log(null == 0);  // false
console.log(undefined == 0); // false

Проверка NaN через ===

console.log(NaN === NaN); // false

Используйте isNaN().

Неожиданная конкатенация

console.log(5 + "5"); // "55", а не 10

Наиболее частые вопросы

Почему typeof null возвращает "object"?

Это историческая ошибка в JavaScript, которую оставили для совместимости.

Чем Number() отличается от parseInt()?

Number() преобразует всю строку в число или возвращает NaN, parseInt() парсит строку до первого недопустимого символа.

Почему пустой массив [] в булевом контексте — true?

Любой объект (включая массив) считается true в булевом контексте.

Итоги

Сегодня мы разобрали:

  • Какие бывают примитивные типы данных.
  • Разницу между явным и неявным преобразованием.
  • Как работают NaN, null и undefined.
  • Что такое falsy значения.
  • Какие ошибки часто встречаются при работе с типами.

Главное: понимание типов данных помогает писать код без неожиданных багов и управлять преобразованиями в нужный момент.