День 14 JavaScript 30 Веса Боса рассказал о фундаментальной разнице между ссылкой и копией. Эти концепции объясняют один из странных аспектов поведения JavaScript.

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

let age = 100;
let age2 = age;
console.log(age, age2); //100,100
age = 200;
console.log(age, age2); //200,100 will not update 2nd variable

Это связано с тем, что для строк, чисел и логических значений создается копия. Поэтому, когда мы меняем переменную в копии, оригинал не меняется.

Однако массив ведет себя иначе.

const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
const team = players;
console.log(players, team);// ['Wes', 'Sarah', 'Ryan', 'Poppy']

Однако, если мы изменим второй массив:

// You might think we can just do something like this:
team[3]= 'Lux'; 
console.log( team);//['Wes', 'Sarah', 'Ryan', 'Lux']
// updates original array as well
console.log( players); //['Wes', 'Sarah', 'Ryan', 'Lux']

Это связано с тем, что team[3] является ссылкой на player[3], а не копией.

Так как же вместо этого сделать копию?

const team2 = players.slice();

Это создаст копию player[]. Теперь, когда мы обновляем team2[], исходный массив не изменится. Интересный совет: когда мы ничего не передаем через slice(), он копирует весь массив.

Конечно, в JavaScript всегда есть несколько способов что-то сделать.

const team3 =[].concat(players);

Объединение также создаст копию.

То же самое можно сказать и об использовании оператора распространения.

`const team4 = [...players];

Еще один способ сделать то же самое.

const team5 = Array.from(players);

Объекты ведут себя одинаково.

const person = {
name: 'Wes Bos',
age: 80
};
const captain =person;
captain.age = 99;
//Now, person.age = 99

Потому что Captain.age делает ссылку на person.age.

Вместо этого сделайте копию.

const cap2 = Object.assign({}, person, {age: 99});

Последняя концепция заключается в том, что такое поведение распространяется только на один уровень вглубь объектов.

const wes = {
   name: 'Wes',
   age: 100,
   social: {
      twitter: '@wesbos',
      facebook: 'wesbos.developer'
   }
}
const dev = Object.assign({}, wes);
//makes copy

Тем не мение:

dev.social.twitter = '@coolman';
console.log(dev.social); //object {twitter:'@coolman, facebook:'wesbos.developer}
console.log(wes.social);//object {twitter:'@coolman, facebook:'wesbos.developer}

На 2 уровне объекта копия не делается. Бос сказал нам, что нет простого способа обойти это, если мы хотим сделать копию на более глубоком уровне объекта. Он дал нам один способ сделать это.

const dev2 = JSON.parse(JSON.stringify(wes));

Это превращает его в строку и сразу же возвращает обратно в массив. Бос особо не рекомендовал этого делать.

Следите за моими учебными заметками по мере того, как я продвигаюсь по JavaScript 30.