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