Logo
Книга для начинающих
ВходРегистрация
/
Программирование
/
Курс 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 не числом, а строкой. Поэкспериментируйте с другими числами тоже.

Коммерческий опыт и Трудоустройство

Полезное

  • Типизация

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

Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "ИИ-помощник":

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

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

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

Нашли ошибку? Есть что добавить? Пулреквесты приветствуются
/
Программирование
/
Курс 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 не числом, а строкой. Поэкспериментируйте с другими числами тоже.

Коммерческий опыт и Трудоустройство

Полезное

  • Типизация

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

Если вы зашли в тупик, то самое время поговорить с нашим асситентом Тота во вкладке "ИИ-помощник":

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

Это нормально 🙆, в программировании одну задачу можно выполнить множеством способов. Если ваш код прошел проверку, то он соответствует условиям задачи. В редких случаях бывает, что решение подогнано под тесты, но это видно сразу.

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

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

Ваше упражнение проверяется по этим тестам

// @ts-check

import { expect, test, vi } from 'vitest';

test('hello world', async () => {
  const consoleLogSpy = vi.spyOn(console, 'log').mockImplementation(() => {});
  await import('./index.js');

  const firstArg = consoleLogSpy.mock.calls.join('\n');

  expect(firstArg).toBe('13');
});
← ПредыдущийСледующий →

Решение учителя откроется через:

20:00

waiting_clock
← ПредыдущийСледующий →