/
Программирование
/
Курс JavaScript
/

Слабая типизация

JavaScript: Слабая типизация

Нам известно про два разных типа данных: числа и строки. Мы, например, можем складывать числа, потому что операция сложения — это операция для типа «числа».

А что, если применить эту операцию не к двум числам, а к числу и строке?

console.log(1 + '7'); // => 17

Несмотря на то что '7' — это строка, а не число, интерпретатор JavaScript выдал ответ '17', как если бы мы складывали две строки. Когда JavaScript видит несоответствие типов, он сам пытается преобразовать информацию. В данном случае он преобразовал число 1 в строку '1', а потом спокойно сделал конкатенацию '1' и '7'.

Слабая типизация

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

Иногда JavaScript доходит до крайностей. Большинство выражений, которые не работают в других языках, в JavaScript отрабатывают. Попробуйте выполнить любую арифметическую операцию, кроме сложения, подставив туда строки — вы увидите, что код выполнится и вернёт NaN (Not a Number):

console.log('one' * 'two'); // => NaN
1 + '7'   →  '17'   (число превратилось в строку, конкатенация)
'7' - 1   →  6      (строка превратилась в число, вычитание)
'one' * 2 →  NaN    (строку нельзя превратить в число)

А как в строгих языках?

В языках со строгой (сильной) типизацией сложить число со строкой не получится — программа остановится с ошибкой. Например, в Python или Ruby выражение 1 + '7' приведёт к ошибке типов: язык требует, чтобы вы явно указали, как преобразовать данные.

При этом языки не делятся ровно на два лагеря — «строгие» и «слабые». Корректнее говорить, что у разных языков разная степень строгости: где-то неявных преобразований почти нет, а где-то их много. JavaScript находится у «слабого» края этой шкалы.

Статическая и динамическая типизация

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

Важно не путать две вещи:

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

Это независимые свойства. JavaScript — язык динамический и слабо типизированный.

Почему JavaScript такой

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

Удобство есть, но у него высокая цена. На практике неявные преобразования создают множество ошибок, которые трудно найти: код может иногда работать, а иногда нет — в зависимости от того, «повезло» ли в конкретном случае с автоматическим преобразованием. Программист замечает это не сразу.

В дальнейших заданиях вы будете встречаться с таким поведением не раз. Часто будет возникать вопрос: «почему мой код работает не так, как я ожидаю?». Слабая типизация красной нитью проходит сквозь всю разработку на JavaScript.

Задание

Выведите на экран результат выражения: 7 - (-8 - -2). Попробуйте сделать число 7 не числом, а строкой. Поэкспериментируйте с другими числами тоже.

Полезное

Команда проекта находится в телеграм-сообществе. Там можно задать любой вопрос и повлиять на проект

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются