Преобразование типов: где JavaScript вас удивит

данные≈ 6 минут

Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.

JavaScript охотно переводит значения из одного типа в другой: что-то вы просите сами, а что-то он делает молча — и именно тихие преобразования порождают самые загадочные баги. Разберём три явных преобразования и главную ловушку — оператор +.

Разделы темы:·

Чаще всего преобразование в строку происходит без вашего участия: alert показывает именно строку, склейка со строкой тоже создаёт строку. Когда нужно явно — есть функция String().

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Со строками всё честно: значение просто записывается буквами, без сюрпризов. Даже null и NaN становятся обычными словами.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Числовое преобразование запускается функцией Number(), а неявно — почти любой математикой: делением, умножением, сравнением. Правила здесь строже, чем у строк, и их стоит выучить наизусть.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
ЗначениеNumber(значение)
"" (пустая строка)0
" 12 "12 — пробелы по краям обрезаются
"12px"NaN
null0
undefinedNaN
true / false1 / 0
js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Авторы языка рассудили так: null — осознанная пустота, «здесь ничего нет», а пустоту посчитать можно — получается ноль. undefined означает «значение вообще не задавали», и превращать его в конкретное число было бы враньём — отсюда NaN, «не число».

Логическое преобразование — самое простое: весь мир делится на два лагеря. Ложных значений восемь: false, 0, -0, 0n, пустая строка "", null, undefined и NaN. Абсолютно всё остальное — true, и это правило молча срабатывает в каждом if. На практике чаще всего встречаются пять из восьми: 0, пустая строка, null, undefined и NaN; false, -0 и 0n попадаются реже. Полный список с разбором ждёт в статье «Условия: if, else и тернарный оператор».

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Лжецов восемь: false, 0, -0, 0n, "", null, undefined, NaN. Всё остальное не врёт.

Подвох прячется в кавычках: "0" — не ноль, а строка из одного символа, поэтому она истинна. То же со строкой из пробела. Язык проверяет не «похоже ли на ноль», а «пустая ли строка».

У оператора + двойная жизнь: если хотя бы один операнд — строка, он бросает математику и склеивает строки. Остальные арифметические операторы — -, *, / — таких сомнений не знают и всегда переводят операнды в числа.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.
ВыражениеРезультатПочему
"5" + 3"53"число подтянулось к строке
"5" - 32минус умеет только считать
2 + 2 + "1""41"слева направо: сначала 4, потом склейка
"" - 1-1пустая строка стала нулём

Правило простое: увидели + рядом со строкой — ждите строку. Данные из полей ввода и URL всегда приходят строками, поэтому перед сложением их нужно явно пропустить через Number() — с этой ловушкой мы уже сталкивались в статье «Диалоги браузера: alert, prompt, confirm», где строку отдавал prompt. Теперь видно, почему так: склеивает не prompt, а сам плюс. Как TypeScript ещё до запуска замечает число, незаметно ставшее строкой, покажет статья «Что компилятор находит в вашем коде из части I» в части III.

  • Явных преобразований три: String(x), Number(x), Boolean(x).
  • Правила Number(): "" и null дают 0, undefined и строки с мусором — NaN, пробелы по краям обрезаются.
  • Falsy-значений восемь: false, 0, -0, 0n, "", null, undefined, NaN. Всё остальное — true, включая "0" и " ".
  • + рядом со строкой склеивает; -, * и / всегда переводят операнды в числа.
  • Данные из форм и URL приходят строками — пропускайте их через Number() до математики.

1/3Что выведет console.log(Number(" 7 "))?

2/3Какое из этих значений превратится в true после Boolean()?

3/3Что выведет console.log("2" + 1 + 1)?

Предскажи вывод

Не запуская код, запишите, что выведет каждая строка. Потом запустите и сверьтесь: расхождения точно покажут, какое правило ещё не улеглось.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Первая строка даёт "10" — плюс со строкой клеит. Дальше работают числа: -1 (пустая строка — это 0), -14 (пробелы обрезались, осталось -9), 1 (null превращается в 0) и NaN (undefined числом не становится).

Почини сумму

Значения пришли из полей формы, поэтому они строки. Исправьте код так, чтобы вместо "10020" вывелось 120.

js
Tab добавляет отступ. Чтобы выйти из редактора, нажмите Escape — фокус перейдёт на кнопку запуска.

Перед сложением превратите строки в числа: console.log(Number(price) + Number(delivery)). Теперь плюс не видит ни одной строки и честно считает.