Найти в Дзене

Передача объектов в функции JavaScript: Почему изменения не всегда работают?

Представьте, что вы дали другу свою книгу, он в ней что-то подчеркнул карандашом, и вернул вам обратно. Когда вы снова открываете книгу, пометки на месте — они остались. Всё логично. Но иногда в JavaScript происходит путаница: вы передаете объект в функцию, меняете его внутри, а снаружи он... не меняется. Или меняется, но не так, как вы ожидали. Давайте разберемся, почему так происходит, на понятных примерах. Обычно с простыми вещами (цифрами, текстом) всё просто. Копируя значение, мы создаем его независимую копию: Здесь внутри функции появилась своя независимая переменная ageInside. Мы изменили её, но на исходную переменную age это никак не повлияло. Это как отксерокопировать документ и исправить копию — оригинал останется прежним. Когда мы работаем с объектами, в переменной хранится не сам объект, а как бы "адрес" его места в памяти компьютера. Это как номер дома, а не сам дом. let person = { name: "Анна" }; Переменная person хранит не Анну целиком, а координаты, где искать информаци
Оглавление

Представьте, что вы дали другу свою книгу, он в ней что-то подчеркнул карандашом, и вернул вам обратно. Когда вы снова открываете книгу, пометки на месте — они остались. Всё логично.

Но иногда в JavaScript происходит путаница: вы передаете объект в функцию, меняете его внутри, а снаружи он... не меняется. Или меняется, но не так, как вы ожидали. Давайте разберемся, почему так происходит, на понятных примерах.

Как мы привыкли работать с числами и строками

Обычно с простыми вещами (цифрами, текстом) всё просто. Копируя значение, мы создаем его независимую копию:

Здесь внутри функции появилась своя независимая переменная ageInside. Мы изменили её, но на исходную переменную age это никак не повлияло. Это как отксерокопировать документ и исправить копию — оригинал останется прежним.

А вот с объектами всё хитрее

Когда мы работаем с объектами, в переменной хранится не сам объект, а как бы "адрес" его места в памяти компьютера. Это как номер дома, а не сам дом.

let person =
{
name: "Анна"
};

Переменная person хранит не Анну целиком, а координаты, где искать информацию о ней.

Когда мы передаем объект в функцию:

-2

Что произошло? Мы скопировали в функцию не саму Анну, а только "адрес" (p получила тот же адрес, что и person). И по этому адресу мы нашли исходный объект и переименовали его (изменили свойство name). Изменения видны снаружи — ведь мы поменяли оригинал.

Почему же бывает, что объект НЕ меняется?

А теперь самое интересное. Посмотрите на этот код:

-3

Почему? Смотрите по шагам:

  1. Создаем объект { name: "Анна" }. Переменная person хранит его адрес (пусть будет улица Ленина, 1).
  2. Вызываем функцию. Внутрь передается копия адреса. Параметр p тоже показывает на улица Ленина, 1.
  3. Внутри функции мы говорим: p = { name: "Мария" }. Это значит — создай новый объект где-то в другом месте (пусть на улица Пушкина, 10) и запиши его адрес в переменную p.
  4. Теперь p показывает на новый объект, а person по-прежнему показывает на старый (улица Ленина, 1).

Связь потеряна. Мы не пошли по старому адресу и не исправили Анну. Мы просто переключили внутренний параметр p на другой объект, а исходная переменная person об этом ничего не знает. То есть мы переопределили переменную p внутри функции.

Точно также это будет работать и, например, с массивами, поскольку массивы в JavaScript - это тоже объекты:

-4

Главное правило

Запомните так:

  • Если внутри функции вы меняете свойства полученного объекта (p.name = ...) — изменения будут снаружи. Вы зашли в квартиру по адресу и переставили мебель.
  • Если внутри функции вы присваиваете новый объект параметру (p = ...) — снаружи ничего не изменится. Вы просто выбросили бумажку с адресом и написали на ней новый адрес, но оригинальная бумажка осталась у вызывающего кода.

Вот и весь секрет.

На этом всё. Подписывайтесь на канал, чтобы ничего не пропустить.