Преобразование типов
Преобразование типов (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)
Практика
- Предскажи результат:
+,+ {},{} +,{} + {} - Напиши функцию, которая безопасно складывает два значения любого типа
- Объясни почему
'2' > '12'возвращаетtrue - Покажи все способы преобразования строки в число