Преобразование типов

Преобразование типов (type coercion) — автоматическое или явное изменение типа значения при операциях, сравнениях и в логических контекстах.

Зачем нужно

JavaScript — динамически типизированный язык. Движок постоянно преобразует типы «под капотом». Незнание правил приводит к багам: '5' + 3 даёт '53', а '5' - 3 даёт 2.

Где используется

  • Арифметические операции со строками
  • Условные проверки (truthy/falsy)
  • Сравнение разных типов
  • Ввод пользователя (всегда строка)

Предпосылки

Типы данных, Boolean, Операторы

Явное преобразование (Explicit)

В строку

String(42);        // '42'
String(true);      // 'true'
String(null);      // 'null'
String(undefined); // 'undefined'
String([1, 2]);    // '1,2'
String({});        // '[object Object]'

// .toString()
(42).toString();     // '42'
(255).toString(16);  // 'ff'
true.toString();     // 'true'
// null.toString();  // TypeError

// Конкатенация с пустой строкой
42 + '';             // '42'
'' + true;           // 'true'

// Template literal
`${42}`;             // '42'
`${null}`;           // 'null'

В число

Number('42');       // 42
Number('3.14');     // 3.14
Number('');         // 0
Number(' ');        // 0
Number('42px');     // NaN
Number(true);       // 1
Number(false);      // 0
Number(null);       // 0
Number(undefined);  // NaN
Number();         // 0
Number([5]);        // 5
Number([1, 2]);     // NaN
Number({});         // NaN

// Унарный +
+'42';       // 42
+true;       // 1
+null;       // 0
+'';         // 0
+'hello';    // NaN

// parseInt / parseFloat (более лояльные)
parseInt('42px');     // 42
parseFloat('3.14m'); // 3.14
parseInt('hello');   // NaN

В boolean

// 8 falsy значений (всё остальное — truthy)
Boolean(false);     // false
Boolean(0);         // false
Boolean(-0);        // false
Boolean(0n);        // false
Boolean('');        // false
Boolean(null);      // false
Boolean(undefined); // false
Boolean(NaN);       // false

// Truthy (примеры «ловушек»)
Boolean('0');       // true — непустая строка!
Boolean('false');   // true — непустая строка!
Boolean();        // true — пустой массив!
Boolean({});        // true — пустой объект!
Boolean(-1);        // true
Boolean(' ');       // true — пробел!

// Двойное отрицание
!!'hello'; // true
!!0;       // false

Неявное преобразование (Implicit)

Оператор + (бинарный)

// Если один операнд — строка, другой преобразуется в строку
'5' + 3;        // '53'
3 + '5';        // '35'
'5' + true;     // '5true'
'5' + null;     // '5null'
'5' + undefined; // '5undefined'
'5' + [1, 2];   // '51,2'
'5' + {};       // '5[object Object]'

// Числовое сложение
5 + 3;           // 8
5 + true;        // 6
5 + null;        // 5
5 + undefined;   // NaN

Операторы - * / %

// Всегда преобразуют в числа
'6' - 2;     // 4
'6' * '2';   // 12
'6' / '3';   // 2
'10' % 3;    // 1
true - 1;    // 0
null * 5;    // 0

Сравнения

== (нестрогое, с приведением)

// Правила ==
0 == false;        // true  (false → 0)
'' == false;       // true  ('' → 0, false → 0)
'' == 0;           // true  ('' → 0)
'0' == 0;          // true  ('0' → 0)
'0' == false;      // true  ('0' → 0, false → 0)
null == undefined; // true  (специальное правило)
null == 0;         // false (null не приводится)
NaN == NaN;        // false

// Массивы и объекты
 == false;       // true  ( → '' → 0, false → 0)
[0] == false;      // true  ([0] → '0' → 0, false → 0)

=== (строгое, без приведения)

0 === false;       // false
'' === false;      // false
'' === 0;          // false
null === undefined; // false
// Всегда используй ===

Логический контекст

// if, &&, ||, !, тернарный — преобразуют в boolean
if ('hello') { /* выполнится */ }
if ('') { /* НЕ выполнится */ }
if (0) { /* НЕ выполнится */ }
if () { /* выполнится! пустой массив — truthy */ }

Таблица преобразований

Значение String Number Boolean
'' '' 0 false
'0' '0' 0 true
'42' '42' 42 true
0 '0' 0 false
42 '42' 42 true
true 'true' 1 true
false 'false' 0 false
null 'null' 0 false
undefined 'undefined' NaN false
`` '' 0 true
[5] '5' 5 true
{} '[object Object]' NaN true
NaN 'NaN' NaN false

Алгоритм ToPrimitive

// При преобразовании объекта в примитив JS вызывает:
// 1. [Symbol.toPrimitive](hint) — если определён
// 2. hint === 'number': valueOf → toString
// 3. hint === 'string': toString → valueOf

const obj = {
  valueOf { return 42; },
  toString { return 'hello'; }
};

console.log(+obj);     // 42 (hint: number → valueOf)
console.log(`${obj}`); // 'hello' (hint: string → toString)
console.log(obj + ''); // '42' (hint: default → valueOf)

Частые ошибки

1. Сложение строки и числа

const input = '5'; // Пользовательский ввод — всегда строка
const result = input + 3; // '53' а не 8!
const correct = Number(input) + 3; // 8
const also = +input + 3; // 8

2. Пустой массив в условии

if () console.log('truthy!'); // Выполнится!
if (.length) console.log('has items'); // НЕ выполнится

3. null в арифметике

null + 1;      // 1 (null → 0)
undefined + 1; // NaN (undefined → NaN)

Практика

  1. Предскажи результат: +, + {}, {} + , {} + {}
  2. Напиши функцию, которая безопасно складывает два значения любого типа
  3. Объясни почему '2' > '12' возвращает true
  4. Покажи все способы преобразования строки в число

Связанные темы

Ресурсы