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 повсюду, и если вы хотите стать мастером этого языка, нужно понимать и его ограничения. Держите данные в чистоте!

Получите ИТ-профессию
В «Яндекс Практикуме» можно стать разработчиком, тестировщиком, аналитиком и менеджером цифровых продуктов. Первая часть обучения всегда бесплатная, чтобы попробовать и найти то, что вам по душе. Дальше — программы трудоустройства.
Начать карьеру в ИТ
Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию Получите ИТ-профессию
Еще по теме
Как устроен спутниковый интернет
Как устроен спутниковый интернет

Надёжно, но с большими задержками.

easy
Как стать фронтенд-разработчиком
116 тысяч рублей в месяц — средняя зарплата для фронтенда. Как им стать

Простая инструкция для начинающих.

easy
Как работает пузырьковая сортировка
Как работает пузырьковая сортировка

Самый простой, но не самый эффективный алгоритм.

easy
Как работает шумоподавление в наушниках
Как работает шумоподавление в наушниках

Противофаза, дай мне силу.

easy
Оптимизация кода
Оптимизация кода

Какая бывает и зачем нужна.

easy
«Я нашла работу в Альфа-Банке за месяц до окончания учёбы»
«Я нашла работу в Альфа-Банке за месяц до окончания учёбы»

Выпускница Практикума Ника Малинина о профессии инженера по тестированию

easy
Что такое протокол
Что такое протокол

Почему компьютеры вообще друг друга понимают

medium
Myspace потеряла архивы за 12 лет. Как не потерять свои
Myspace потеряла архивы за 12 лет. Как не потерять свои

Почему так сложно сберечь важные данные и как с этим быть вообще.

easy
Зачем нужен нормализатор CSS
Зачем нужен нормализатор CSS

Хорошая практика веб-разработчиков.

medium
Как писали игры для приставок: чудеса оптимизации и жёсткий кодинг

Для всех, кто вырос, проходя восьмибитного Марио.

medium
medium