Копии объектов и массивов. spread оператор

Создадим поверхностную копию объекта

С помощью цилка

function someCopy(mainObj) { //  создаем функцию и задаем аргумент, куда будем передавать наш основной объект.
    let objCopy = {}; // тут будет наша копия

    let key;
    for (key in mainObj) { // перебираем наш основной объект
        objCopy[key] = mainObj[key]; // Напоминаю, что если имя свойства в переменной, то обратиться мы можем только через []
        //в objCopy создаем новое свойство key - оно будет содержать такое же значение как и в главном объекте
        // далее просто делаем копию нашего главного объекта.
        // проше говоря мы пройдемся по нашему основному объекту и скопируем все в копию.

    }

    return objCopy; // возвращаем наружу
}

const numbers = { // создаем новый объект длдя проверки
    a: 2,
    b: 5,
    c: {
        x: 7,
        y: 4
    }

};

const newNumbers = someCopy(numbers); // создаем переменую для нашей копии и помещаем в нее функцию копирования и аргумент с нужным объектом

newNumbers.a = 10; // меняем в копии значение

// Проверяем

console.log(newNumbers); // { a: 10, b: 5, c: { x: 7, y: 4 } }
// мы Получили два разных объекта
console.log(numbers); // { a: 2, b: 5, c: { x: 7, y: 4 } }
// НО ЕСТЬ ОДНО НО если мы сделаем так:
newNumbers.c.x = 10;
console.log(newNumbers); // x переписалась в обоих случаях 
console.log(numbers);

Когда мы так клонируем объекты есть два важных понятия! Это глубокие и поверхностные копии объектов. Выше мы создали поверхностную копию. Она берет все обычные свойства которые были в родителе и создает независимые структуры, но как только появляется вложенная структура массив или объект как в нашем случаи, то это свойство опять будет иметь ссылочный тип данных.

С помощью метода Object.assign()

const numbersTwo = {
    a: 2,
    b: 5,
    c: {
        x: 7,
        y: 4
    }
};

const add = {
    d: 17,
    e: 20
};

console.log(Object.assign(numbersTwo, add)); // 1 - аргумент указываем объект в который мы хотим все поместить
//                                              2 - объект который помещаем
// фишка в том, что тоже самое мы можем сделать и с пустым объектом и получится просто копия
const clone = Object.assign({}, add);
clone.d = 20;
console.log(clone); // { d: 20, e: 20 } наша копия работает
console.log(add); // { d: 17, e: 20 } 

Поверхностная копия массива

С помощью slice()

Мы можем использовать так же цикл как и с объектом, но есть способ получше.

const oldArray = ['a', 'b', 'c']; // Наш основной массив

const newArray = oldArray.slice(); // создаем новую переменную и в нее кладем наш массив и обращаемся к методу slice( )

newArray[1] = 'asfds';  // менем второй элемемент
console.log(newArray); // [ 'a', 'asfds', 'c' ] // Копия работает
console.log(oldArray); // [ 'a', 'b', 'c' ]

Оператор spread

В ES6 такой опертор повился для массивов, а в ES9 и для объектов. Но неофициально его использовали уже в ES8. spread оператор разварачивает элементы массива в другом массиве, его используют для создания копий или же для слияния. Выглядит spread оператор как три точки ...

const video = ['youtube', 'viemo', 'rutube'], // создаем массив
    blogs = ['wordpress', 'livejournal', 'blogger'], // еще один
    internet = [...video]; //  ... - это spread оператор, он развернул элементы из video в массив internet 
    video[0] = 'ddddd'; // меняем значение для первого элемента в массиве video.
    console.log(internet); // [ 'youtube', 'viemo', 'rutube' ] - массив где мы использовали ...
    console.log(video); // [ 'ddddd', 'viemo', 'rutube' ]  - массив которого делали копию, первый элемент поменялся только у оригинала. Копия удалась.
    // С помощью spread мы можем слить несколько массивов в единый новый массив и так же, что-то добавить еще.
    internet = [...video, ...blogs, 'vk', 'facebook']; // сливаем 2 масива и добавляем еще 2 элемента - 'vk', 'facebook'
console.log(internet);
/*
[                       Получился вот такой массив, содержащий в себе все из массива video и blogs и 2 доп элемента
'ddddd',
'viemo',
'rutube',
'wordpress',
'livejournal',
'blogger',
'vk',
'facebook'
]
*/

Еще один пример работы spread:

// cоздаем простую функцию с 3 - аргументами
function log (a,b,c) {
    console.log(a); // 2          
    console.log(b); // 5
    console.log(c); // 7
}

const num = [2,5,7];   // и к нам вот пришел такой массив и нужно эти элементы добавить в наши 3 аргумента в функции

log(...num); // вызываем нашу функцию и используем spread оператор на нашем массиве и все. Выше видно какая цифра и в какой аргумент пошла.

Теперь spread оператор и копия объекта:

const q = {
    one: 1,
    two: 2
};

const newQ = {
    ...q
};
console.log(newQ); // { one: 1, two: 2 }
// Все очень просто.