Что произойдет, если попытаться изменить символ в строке?
let firstName = 'Alexander'
// Код выполнится без ошибок
firstName[0] = 'B'
console.log(firstName) // => Alexander
Как это ни странно, но значение переменной firstName
останется прежним, хотя код выполнится без ошибок. Так происходит из-за неизменяемости примитивных типов в JavaScript — язык не дает никакой физической возможности поменять строку. Неизменяемость примитивных типов важна по многим причинам, ключевая — производительность. Но что делать, если нам действительно нужно ее изменить? Для этого и существуют переменные:
let firstName = 'Alexander'
// Код выполнится без ошибок
firstName = 'Blexander'
console.log(firstName) // => Blexander
Есть большая разница между изменением значения переменной и изменением самих данных, которые хранятся в этой переменной. Примитивные типы в JavaScript поменять нельзя, а заменить значение переменной — без проблем.
Слабая типизация
Нам известно про два разных типа данных: числа и строки. Мы, например, можем складывать числа, потому что операция сложения — это операция для типа «числа».
А что, если применить эту операцию не к двум числам, а к числу и строке?
console.log(1 + '7') // => 17
Несмотря на то, что 1
— это число, а не строка, интерпретатор JavaScript выдал ответ 17
, как если бы мы складывали две строки. Когда JavaScript видит несоответствие типов, он сам пытается преобразовать информацию. В данном случае он преобразовал число 1
в строку '1'
, а потом спокойно сделал конкатенацию '1'
и '7'
.
Не все языки так делают. JavaScript — это язык со слабой типизацией. Он знает о существовании разных типов (числа, строки и др.), но относится к их использованию не очень строго, пытаясь преобразовывать информацию, когда это кажется разумным. Иногда JavaScript даже доходит до крайностей. Большинство выражений, не работающих в других языках, прекрасно работают в JavaScript. Попробуйте выполнить любую арифметическую операцию (кроме сложения), подставив туда строки или любые другие типы данных (кроме ситуации, когда оба операнда – это числа или строки, содержащие только число) — вы увидите, что они всегда будут работать и возвращать NaN
, что довольно логично.
const result = 'one' * 'two'
console.log(result) // => NaN
В языках со строгой типизацией сложить число со строкой не получится.
JavaScript был создан для интернета, а в интернете вся информация — это строки. Даже когда вы вводите на сайте номер телефона или год рождения, на сервер эта информация поступает не как числа, а как строки. Поэтому авторы языка решили, что автоматически преобразовывать типы — правильно и удобно.
Такое автоматическое неявное преобразование типов с одной стороны и правда удобно. Но на практике это свойство языка создает множество ошибок и проблем, которые трудно найти. Код может иногда работать, а иногда не работать — в зависимости от того, «повезло» ли в конкретном случае с автоматическим преобразованием. Программист это заметит не сразу.
В дальнейших заданиях вы будете встречаться с таким поведением не раз. Часто будет возникать вопрос «почему мой код работает не так, как я ожидаю?».
Слабая типизация красной нитью проходит сквозь всю разработку на Javascript.