JavaScript: Неизменяемость примитивных типов
Представим, что у нас есть строка, и мы хотим заменить в ней один символ, например первую букву имени:
let greeting = 'Hello';
greeting[0] = 'J';
console.log(greeting); // => Hello (не изменилось!)В отличие от некоторых языков, где такая попытка приводит к ошибке, в JavaScript присваивание по индексу просто тихо игнорируется: строка не меняется (а в строгом режиме это вызовет ошибку TypeError). Причина одна: строки в JavaScript нельзя изменять по частям. После создания они становятся неизменяемыми (или, как говорят программисты, иммутабельными).
Почему строки неизменяемые?
Примитивные типы (строки, числа, логические значения) в JavaScript менять нельзя. Это даёт важные преимущества:
- Безопасность: значения не изменятся случайно.
- Производительность: с неизменяемыми значениями проще работать внутри движка.
- Предсказуемость: меньше неожиданных эффектов при передаче данных в функции.
А как тогда «изменить» строку?
Если нужно «изменить» строку, создают новую на основе старой и сохраняют её в ту же переменную. Например, заменим первую букву:
const word = 'hello';
const fixed = 'H' + word.slice(1);
console.log(fixed); // => Helloword = 'hello'
word[0] = 'H' → ничего не происходит, строки неизменяемы
'H' + word.slice(1)
└────────┬────────┘
'Hello' ← создана новая строкаПереприсвоить переменную целиком тоже можно — но это создаёт новую строку, а не меняет старую:
let greeting = 'Hello';
greeting = 'Jello';
console.log(greeting); // => JelloНовая переменная или та же?
Переиспользовать переменную стоит только тогда, когда речь идёт об одной и той же сущности. Если это уже другие данные, лучше завести отдельную переменную:
// Одна и та же строка, просто обновляем
let name = 'Alexander';
name = 'Blexander';
// Разные сущности — лучше разные переменные
const firstName = 'Alexander';
const correctedFirstName = 'Blexander';Попытка «запихать» все строки в одну переменную запутывает код: переменная перестаёт говорить, что в ней хранится.
Вывод
Примитивные типы данных в JavaScript (строки, числа, логические значения) являются неизменяемыми (immutable). Это означает, что после создания их значение изменить нельзя. Поменять один символ в строке невозможно — любые «изменения» происходят путём создания нового значения и переопределения переменной.
Задание
Вам даны три константы с фамилиями разных людей. Составьте и выведите на экран в одну строку слово из символов в таком порядке:
- Третий символ из первой строки
- Второй символ из второй строки
- Четвертый символ из третьей строки
- Пятый символ из второй строки
- Третий символ из второй строки
Попробуйте использовать интерполяцию: внутри фигурных скобок можно помещать не только целые переменные, но и отдельные символы с помощью квадратных скобок.
JavaScript: Неизменяемость примитивных типов
Представим, что у нас есть строка, и мы хотим заменить в ней один символ, например первую букву имени:
let greeting = 'Hello';
greeting[0] = 'J';
console.log(greeting); // => Hello (не изменилось!)В отличие от некоторых языков, где такая попытка приводит к ошибке, в JavaScript присваивание по индексу просто тихо игнорируется: строка не меняется (а в строгом режиме это вызовет ошибку TypeError). Причина одна: строки в JavaScript нельзя изменять по частям. После создания они становятся неизменяемыми (или, как говорят программисты, иммутабельными).
Почему строки неизменяемые?
Примитивные типы (строки, числа, логические значения) в JavaScript менять нельзя. Это даёт важные преимущества:
- Безопасность: значения не изменятся случайно.
- Производительность: с неизменяемыми значениями проще работать внутри движка.
- Предсказуемость: меньше неожиданных эффектов при передаче данных в функции.
А как тогда «изменить» строку?
Если нужно «изменить» строку, создают новую на основе старой и сохраняют её в ту же переменную. Например, заменим первую букву:
const word = 'hello';
const fixed = 'H' + word.slice(1);
console.log(fixed); // => Helloword = 'hello'
word[0] = 'H' → ничего не происходит, строки неизменяемы
'H' + word.slice(1)
└────────┬────────┘
'Hello' ← создана новая строкаПереприсвоить переменную целиком тоже можно — но это создаёт новую строку, а не меняет старую:
let greeting = 'Hello';
greeting = 'Jello';
console.log(greeting); // => JelloНовая переменная или та же?
Переиспользовать переменную стоит только тогда, когда речь идёт об одной и той же сущности. Если это уже другие данные, лучше завести отдельную переменную:
// Одна и та же строка, просто обновляем
let name = 'Alexander';
name = 'Blexander';
// Разные сущности — лучше разные переменные
const firstName = 'Alexander';
const correctedFirstName = 'Blexander';Попытка «запихать» все строки в одну переменную запутывает код: переменная перестаёт говорить, что в ней хранится.
Вывод
Примитивные типы данных в JavaScript (строки, числа, логические значения) являются неизменяемыми (immutable). Это означает, что после создания их значение изменить нельзя. Поменять один символ в строке невозможно — любые «изменения» происходят путём создания нового значения и переопределения переменной.
Задание
Вам даны три константы с фамилиями разных людей. Составьте и выведите на экран в одну строку слово из символов в таком порядке:
- Третий символ из первой строки
- Второй символ из второй строки
- Четвертый символ из третьей строки
- Пятый символ из второй строки
- Третий символ из второй строки
Попробуйте использовать интерполяцию: внутри фигурных скобок можно помещать не только целые переменные, но и отдельные символы с помощью квадратных скобок.
Ваше упражнение проверяется по этим тестам
// @ts-check
import { expect, test, vi } from 'vitest';
test('data types immutability', async () => {
const consoleLogSpy = vi.spyOn(console, 'log');
await import('./index.js');
const firstArg = consoleLogSpy.mock.calls.join('\n');
expect(firstArg).toBe('hodor');
});Решение учителя откроется через:
20:00
