JavaScript для новичков: чем опасны нестрогие типы данных

JavaScript для новичков: чем опасны нестрогие типы данных

В JavaScript есть удобная штука, которая может сильно вам навредить.

Когда начинаешь изучать JavaScript, сначала чувствуешь эйфорию: очень легко работать с переменными, не нужно следить за типами, просто назвал и пользуешься. Но с великой свободой приходит великая ответственность. Если вы только начинаете пользоваться этим языком, обратите внимание на нюанс с типами данных.

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

  • в интернет-магазине, когда вы кликаете «Добавить в корзину», и счётчик товаров сразу обновляется;
  • когда вы при регистрации вводите неправильный имейл, и форма сразу подсвечивает вам, что он неверный;
  • в социальных сетях в браузере, когда новое сообщение приходит без перезагрузки страницы;
  • там же, когда вы можете перейти из личных сообщений в новости, продолжая слушать любимую музыку;
  • в любой браузерной игре;
  • когда на сайтах есть какая-то анимация;
  • когда сайт собирает данные для статистики;
  • когда посреди чтения статьи на вас бросается бесящая нападайка.


JavaScript — это язык, с помощью которого веб-страницы оживают, в них динамически подгружаются данные, появляются всплывающие окна, выпадающие элементы и миллион других вещей.

JavaScript работает во всех современных браузерах: если вы читаете эту страницу, то прямо сейчас ваш браузер выполняет какой-нибудь JavaScript. Вы можете открыть консоль и написать код на JavaScript, и он выполнится на этой странице.

Что за типы

В любом языке программирования вы встретите типы данных: числа, строки, массивы и т. д. Типы данных говорят компьютеру, как себя вести: например, на строку он выделяет одно количество памяти, а на число — другое. Числа он умеет складывать и умножать, а в строках — находить нужные буквы и слова.

Если сказать компьютеру «Запомни число 2000», он закодирует его особым образом. Это число можно будет умножать, вычитать из него, использовать как счётчик и сделать что-то две тысячи раз. Можно сказать «Увеличь на один», и компьютер без проблем выдаст 2 001. Если сказать «Уменьшай на один», у компьютера не возникнет сомнений, что нужно выдать 1 999.

А если сказать «Вот тебе строка с текстом ‘2000’», компьютер запомнит это как двойку и три нуля. Он понятия не имеет, что эти знаки означают: он просто запомнил последовательность символов. Можно попросить его посчитать, сколько в этой строке символов и сколько из них нулей. Можно попросить достать первый или последний символ строки (двойку или ноль). Можно попросить развернуть строку (0002). Можно добавить к этой строке слово «год». Но если сказать «Уменьшай на единицу», то компьютер в жизни не догадается, что от него ждут 1 999. В лучшем случае он подумает, что от него просят откусить от строки последний символ, и получится 200.

Строгие и нестрогие типы

Есть языки со строгими типами данных: чтобы использовать переменную с числом, нужно сначала объявить переменную как числовую, а потом уже что-то с ней делать. Записать букву в числовую переменную нельзя. Сложить число со строкой нельзя. Сравнить число со строкой тоже нельзя. Вот пример, который в большинстве строгих языков выдаст ошибку:

2000 == ‘2000’

> Ошибка: невозможно сравнить строку с числом

> Или вернёт false, потому что строка не равна числу

В JavaScript всё не так строго. Здесь достаточно просто начать пользоваться переменной, и язык сам определит, какого она будет типа. Если в JavaScript попытаться сложить строку и число, язык сам приведёт данные к одному типу и не выдаст ошибку. А если их сравнивать с помощью нестрогого оператора сравнения, то будет магия:

if(2000 == '2000'){
  alert('Я только что сравнил число и строку, и мне за это ничего не было!'); }

Что тут происходит: JavaScript видит, что сравниваются разные типы данных, и приводит их к чему-то одному. Приведение происходит автоматически под капотом, а вы видите только результат.

Чисто по-человечески это классно: я хотел сравнить 2 000 и 2 000, и у меня всё получилось. Зачем мне разбираться с этими типами?

В чём проблема

Если невнимательно следить за своими типами данных, то можно получить непредсказуемо работающий код. Например, у вас в переменной случайно оказалось не число, а строка, и если вы складываете её с числом, то… В общем, смотрите:

let year = '2000';
//В переменной строка, а не число. Мы могли получить её от пользователя и могли загрузить из базы данных. Мы думаем, что это число 2 000, но это строка — два-ноль-ноль-ноль.
if (year > 1999) {
  // Мы ожидаем, что если эта часть кода выполняется, то мы работаем с годами больше 1999. И предполагаем, что это числа.
  let year2 = year + 20;
  // Резонно ожидать, что в переменной year2 сейчас будет лежать 2000 + 20 = 2020 год. Но…
  console.log(year2);
}

В консоли после такого кода выведется не 2020, а ‘200020’. Почему? Потому что year была строкой и её не сложили с числом, а соединили (это называется конкатенация). Просто приклеили двадцатку к существующей строке.

Что делать

Чтобы справиться с этим разнобоем, стоит следить за типами и вручную приводить их куда надо. Особенно когда данные приходят от пользователя или из внешних источников. Вот пример:

let year = '2000';
//Допустим, мы всё ещё имеем на входе некую строку.
let parsedYear = Number(year);
//Мы попросили JavaScript явным образом привести year к числу. Теперь в этой переменной точно число. JavaScript отвечает.
if (parsedYear > 1999) {
  let year2 = parsedYear + 20;
  console.log(year2);
}
//Выдаст ожидаемый результат 2020

Вот что нам поможет:

toString(), String() — перевести в строку;

parseInt(), Number() — перевести в целое число;

parseFloat() — перевести в число с дробью.

Почему так сложно

Язык JavaScript создавался как простой язык для скриптования веб-страниц. Никто не думал, что много лет спустя он станет одним из самых распространённых языков веб-приложений. Поэтому изначальный JavaScript мог себе позволить некоторые вольности и допущения, которые были некритичны для тех условий, но резко упрощали работу. Например, приятно ведь не думать о типах данных, а просто использовать их?

Но теперь JavaScript повсюду, и если вы хотите стать мастером этого языка, нужно понимать и его ограничения. Держите данные в чистоте!

Веб-разработка — это новый черный
А мы знаем толк в моде и поможем освоить новую специальность за полгода.
Посмотреть
Фронтенд — это новый черный
Еще по теме
prev
next
119 тысяч рублей за то, чтобы делать приложухи — это справедливо?

Краткий гид по работе мобильного разработчика

Функции. Зачем они нужны и как их писать, чтобы вас уважали программисты
Функции. Зачем они нужны и как их писать, чтобы вас уважали программисты

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

Как программируют станки на заводах
Как программируют станки на заводах

От токарных до лазерных

Все опять заговорили про VPN. Что это такое, объясни мне!

Мы не можем вам сказать. Но можем показать.

Чем занимаются бэкенд-разработчики
Чем занимаются бэкенд-разработчики

Никто не видит, но все пользуются.

WebStorm: это что и зачем?
WebStorm: это что и зачем?

Разбираем один из любимых редакторов кода всея Руси.

MySQL — царица баз
MySQL — царица баз

Она сложная, но с ней всё просто.

Flipper Zero: как устроен хакерский тамагочи
Flipper Zero: как устроен хакерский тамагочи

И сколько на нём можно заработать.

ООП: зачем нужны абстракции и классы
Зачем нужны абстракции и интерфейсы

И что это вообще такое?

Что о вас на самом деле знают Google и Facebook (и все остальные)

Если коротко — они знают о вас почти всё. Но с этим тоже можно что-то сделать.

medium