«Единственный способ творить великие дела – это любить то, что ты делаешь»
JavaScript


Игра на «Морской Бой» на JavaScript: Простая Игра и Игра для Двоих


Передача данных по ссылке и по значению. Что это такое?

На эту тему стоит обратить особое внимание, ее нужно понять.

Также здесь представлен пример функции для клонирования объекта. Как в JavaScript копировать объект? Читайте далее.



Логика или Алогика

Рассмотрим 2 примера. Сначала в обоих случаях пробуем рассуждать логически.

Пример 1.1

let a = 5,
    b = a;

b = b + 5;

console.log(b);
console.log(a);

Результат


10
5

1. Создается переменная a = 5.

2. Переменной b присваивается переменная a.

3. Меняем значение переменной b.

4. Значение переменной a остается прежним.

В примере 1.1 код работает правильно. Противоречий нет.

Пример 1.2

const obj = {
    a: 5,
    b: 1
};

const copy = obj;

copy.a = 10;

console.log(copy);
console.log(obj);

Результат


{ a: 10, b: 1 }
{ a: 10, b: 1 }

1. Создается объект obj. У него два свойства a и b.

2. Создается переменная, в которую заносится объект obj. copy = obj.

По логике copy - это копия объекта obj.

3. Меняем значение свойства a объекта copy.

4. При этом меняется и значение свойства a объекта obj.

В примере 1.2 код работает правильно. Но с точки зрения логики - есть несоответствие. Почему так происходит? Почему код во 2-м примере работает на первый взгляд Алогично.

Простые типы данных - Передача по значению

Простые типы данных: строки, числа, булевы значение - передаются по значению.

То есть в примере 1.1 выражение b = a означает, что переменная b - это копия переменной a.

Поэтому при изменении значения переменной b, значение исходной переменной a - остается прежним.

Объекты - Передача по ссылке

Объекты (смотрим здесь - что к ним относится) - передаются по ссылке.

То есть в примере 1.2 выражение const copy = obj означает, что в переменную copy передается НЕ копия объекта obj, а ссылка на объект (через переменную copy, мы ссылаемся на объект obj).

То есть запись copy.a = 10 означает, что через copy (через ссылку на объект obj) происходит изменение значения свойства a объекта obj.

Так работает JavaScript.

Клонирование объекта

Итак, мы выяснили, что если переменной присвоить объект, то в переменную передается ссылка на объект, но не сам объект.

Но как сделать копию объекта?

В примере 3.1 представлена функция для клонирования объекта.

Пример 3.1

function copy(mainObj) {
    let objCopy = {}; 
    
    let key;
    for (key in mainObj){
        objCopy[key] = mainObj[key];
    }

    return objCopy;
}

// Объект для клонирования
const numbers = {
    a: 3,
    b: 5,
    c: 8
};

//Клонирование объекта numbers в переменную newNumbers
const newNumbers = copy(numbers);

// Меняется значение одного из свойства объекта newNumbers
newNumbers.a = 10;

console.log(newNumbers);
console.log(numbers);

Результат


{ a: 10, b: 5, c: 8 }
{ a: 3, b: 5, c: 8 }

1. Функция для клонирования объекта имеет один аргумент mainObj. Таким образом в нее передается объект для клонирования.

2. Внутри функции создается новый (пустой) объект objCopy - в него будут копироваться свойства передаваемого в функцию объекта.

3. Затем при помощи конструкции for-in перебираются все свойства объекта mainObj. При этом они сразу же заносятся (копируются) в новый объект objCopy.

Функция возвращает копию объекта return objCopy.

4. Далее создается тестовый объект для клонирования numbers.

И происходит клонирование: newNumbers = copy(numbers). При этом в функцию copy передается объект numbers.

5. Делаем проверку (нужно убедиться, что не повторится ситуация из примера 1.2): меняем значение свойства a нового объекта newNumbers.

6. В результате видно: значение свойства a исходного объекта numbers осталось неизменным. Значит функция для клонирования объекта работает. И newNumbers - это именно копия объекта numbers.

Поверхностное клонирование - Вложенные объекты

Вернемся к примеру 3.1 и рассмотрим ситуацию, когда одно из свойств объекта для клонирования также является объектом (или массивом).

Что произойдет при клонировании вложенного объекта?

Пример 4.1

function copy(mainObj) {
    let objCopy = {}; 
    
    let key;
    for (key in mainObj){
        objCopy[key] = mainObj[key];
    }

    return objCopy;
}

// Объект для клонирования
const numbers = {
    a: 3,
    b: 5,
    c: {
        x: 2,
        y: 8
    }
};

//Клонирование объекта numbers в переменную newNumbers
const newNumbers = copy(numbers);

// Изменение родительского свойства нового (клонированного) объекта
newNumbers.a = 10;
// Изменение вложенного свойства нового (клонированного) объекта
newNumbers.c.x = 13;

console.log(newNumbers);
console.log(numbers);

Результат


{ a: 10, b: 5, c: { x: 13, y: 8 } }
{ a: 3, b: 5, c: { x: 13, y: 8 } }

Как видно из примера: при клонировании вложенного объекта происходит передача данных по ссылке. Что это значит?

В примере 4.1 происходит поверхностное клонирование.

1. При изменении родительских свойств клонированного объекта newNumbers.a = 10, значения свойств исходного объекта остаются прежними.

2. Если же одно из свойств исходного объекта тоже является объектом (массивом), то есть при клонировании вложенной структуры (вложенного объекта, массива) - эта структура имеет ссылочный тип данных.

Из примера видно, что при изменении вложенных свойств клонированного объекта newNumbers.c.x = 13, значения вложенных свойств исходного объекта также изменяются.

Поэтому такое клонирование называется поверхностным.

Глубокого клонирования в рассмотренном примере (клонирования вложенных объектов) НЕ происходит. Вложенные свойства клонированного объекта ссылаются на вложенные свойства исходного объекта.

Глубокое клонирование объекта, когда происходит копирование вложенных структур (вложенных объектов) будет рассматриваться позднее.



Читайте также...



Отзывы и комментарии:

Комментариев нет...

Оставить отзыв:

Ваше Имя:

Текст комментария:

Ответьте на вопрос:

Сколько дней в Високосном году?


Рунет - Часть 2
Передача данных по ссылке и по значению – Клонирование объекта
52
Условия if else - Конструкция switch case - Тернарный оператор
68
Циклы while и for - Операторы break и continue
86
Практика часть 2 – Циклы и Условия
93
Объявление функций – Стрелочные функции ES6
105
Методы и свойства строк и чисел - Метод substr - Индекс строки
38
Практика часть 3 - Используем функции
81
Что такое callback-функция - Аргумент другой функции
54
Свойства и методы объектов - Деструктуризация объектов ES6
66
Методы массивов - Перебор элементов массива - Псевдомассивы
75
Метод assign() – Копирование исходных объектов в целевой объект
42
Копирование массивов - Оператор spread
65
Прототипное Программирование - Прототип и Экземпляр Объекта
44
Свойство proto - Методы Object.create и Object.setPrototypeOf
65
Практика часть 4 - Используем функции как методы объекта
8
Помощь сайту
Yandex-деньги/Ю-Money
410011236419322
Перевод на карту СБ
4276 1300 1671 5819
WebMoney
R711879515665 Z861169301432

Тематические публикации
Популярные заметки
Последние заметки