Прокачай свои знания о строках в JavaScript с этой статьей!

Cover Image for Прокачай свои знания о строках в JavaScript с этой статьей!

Короткая статья о том, как работают строки в JavaScript. Рассматривается неизменяемость строк, механизмы сравнения и оптимизация выделения памяти для строк.

Начнем с вопросов: что выведет этот код?

const str = "Hello";
str[2] = "a";
console.log(str);

А если заменить const на let?

let str = "Hello";
str[2] = "a";
console.log(str);

Попробуйте ввести этот код в консоль браузера и проверить, что получится.

В JavaScript строки являются неизменяемыми. Это означает, что независимо от того, объявлена ли переменная через let или const, значение не изменится, и в обоих случаях будет выведено "Hello".

Но что, если мы добавим оператор присваивания с конкатенацией строк:

const str = "Hello";
str += " World";
console.log(str);

Данный код выполнится с TypeError: Assignment to constant variable, из-за того, что мы объявили строку как const. Заменим его на let:

let str = "Hello";
str += " World";
console.log(str);

В JavaScript строки копируются при присваивании значения из одной строки в другую. Следовательно, этот код выведет "Hello World". В конце статьи мы пошагово разберем, как работает такой код.

Давайте разберем копирование строк чуть подробнее. Что выведет этот код и почему?

const str1 = 'Hello';
const str2 = str1;

console.log(str1 === str2);

При копировании строки в JavaScript создается новая ссылка на объект строки, но сама строка не дублируется в памяти. Следовательно, при сравнении str1 === str2 будет выведено true. Объясним подробнее:

  • Создание строки 'Hello': Выделение памяти для хранения строки 'Hello'.

  • Присваивание значения другой переменной: Переменная str2 получает ссылку на тот же объект строки в памяти, что и переменная str1.

  • Сравнение переменных: При сравнении str1 === str2 JavaScript сначала сравнивает значения ссылок, а не сами строки. Поскольку обе переменные ссылаются на один и тот же объект строки в памяти, сравнение вернет true.

А если мы не будем копировать строку и создадим новую с таким же значением как у первой. Что выведет этот код, почему и как он работает?

const str1 = 'Hello';
const str2 = 'Hello';

console.log(str1 === str2);
  • При объявлении const str1 = 'Hello' в памяти выделяется место для хранения строки 'Hello'.

  • Затем, при объявлении const str2 = 'Hello', JavaScript оптимизирует использование памяти и создает только один объект строки для обеих переменных. Вместо того, чтобы выделять новое место в памяти для строки 'Hello', JavaScript обнаруживает, что строка 'Hello' уже существует в памяти (в результате объявления str1), и просто создает ссылку на эту же строку для переменной str2.

  • При выполнении console.log(str1 === str2) происходит сравнение переменных str1 и str2. Поскольку обе переменные ссылаются на один и тот же объект строки в памяти, сравнение вернет true.

А что выведет код ниже и почему?

const str1 = 'Hello';
const str2 = 'Hello2';

console.log(str1 === str2);

В данном случае переменные str1 и str2 содержат разные строки: 'Hello' и 'Hello2'.

  • При объявлении const str1 = 'Hello' в памяти выделяется место для хранения строки 'Hello'.

  • Затем, при объявлении const str2 = 'Hello2', JavaScript создает новый объект строки для значения 'Hello2' и выделяет ему отдельное место в памяти.

  • После этого, при выполнении console.log(str1 === str2) происходит сравнение переменных str1 и str2. Поскольку они ссылаются на разные объекты строк в памяти, сравнение вернет false.

Разберем подробнее пример с конкатенацией строк:

const str1 = 'Hello';
const str2 = str1 + '2';

console.log(str1 === str2);
  • При объявлении const str1 = 'Hello' в памяти будет выделена память для строки 'Hello'.

  • При объявлении const str2 = str1 + '2' происходит конкатенация строк. JavaScript создает новую строку, объединяя содержимое str1 (которая содержит 'Hello') и строки '2'. Поскольку строки в JavaScript неизменяемы, создается новый объект строки для результата конкатенации, в данном случае 'Hello2'.

  • После этого, при выполнении console.log(str1 === str2), поскольку str1 содержит 'Hello', а str2 содержит 'Hello2', они указывают на разные объекты строки в памяти, и сравнение вернет false.