본문 바로가기

JavaScript30 Challenge

[JavaScript30] Day 14

JavaScript References VS Copying

 

// start with strings, numbers and booleans
let age = 100;
let age2 = age;
console.log(age, age2);
age = 200;
console.log(age, age2);

let name = 'wes';
let name2 = name;
console.log(name, name2);
name = 'wesley';
console.log(name, name2);

 

 

age2 = age 이지만,

age가 재할당 된다고 해서, age2도 재할당되는 것은 아닙니다.

이것은 string에서도 동일합니다.

 

// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

// and we want to make a copy of it.
const team = players;
console.log(players, team);

// You might think we can just do something like this:
team[3] = 'Lux';

 

 

team의 3번째 인덱스를 수정했더니, team도 바뀌고, plyer도 바뀌었습니다.

이처럼 배열은 업데이트하면 항상 새로 참조됩니다.

그래서 배열을 사용할 때는 배열의 사본을 만들어 새로운 참조가 일어나지 않도록 하는 것이 좋습니다.

 

 

배열의 사본을 만들어 team이 업데이트가 되어도 palyers는 그대로 유지하는 방법은 여러 가지가 있습니다.

 

// Let's say we have an array
const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];

// and we want to make a copy of it.
const team = players;
console.log(players, team);

// 방법 1
// So, how do we fix this? We take a copy instead!
const team2 = players.slice();

// 방법 2
// or create a new array and concat the old one in
const team3 = [].concat(players);

// 방법 3
// or use the new ES6 Spread
const team4 = [...players];
team4[3] = 'heeee hawww';
console.log(team4);

// 방법 4
const team5 = Array.from(players);

 

방법 1에 대한 확인

 

방법 4에 대한 확인

 

 

Object.assign()을 사용해 object를 copy하는 방법

 

// with Objects
const person = {
  name: 'Wes Bos',
  age: 80
};

// how do we take a copy instead?
const cap2 = Object.assign({}, person, { number: 99, age: 12 });
console.log(cap2);

 

 

모두 1단계 깊이에 대한 Arrays and Objects의 copy입니다.

빈 객체에  모든 속성과 값을 덮어쓰는 방법이 있습니다.

 

// Things to note - this is only 1 level deep - both for Arrays and Objects.
// lodash has a cloneDeep method, but you should think twice before using it.
const wes = {
  name : 'Wes',
  age: 100,
  social: {
    twitter: '@wesbos',
    facebook: 'wesbos.devloper'
  }
};

console.log(wes);

const dev = Object.assign({}, wes);

 

name을 변경하는 테스트

 

social을 변경하는 테스트

 

social의 twitter는 깊이 1이 아니기 때문에 다른 방법으로 바꿔줄 수 있습니다.

 

// Things to note - this is only 1 level deep - both for Arrays and Objects.
// lodash has a cloneDeep method, but you should think twice before using it.
const wes = {
  name : 'Wes',
  age: 100,
  social: {
    twitter: '@wesbos',
    facebook: 'wesbos.devloper'
  }
};

console.log(wes);

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

 

 

왜 dev는 wes.social도 변화했는데, dev2는 wes.social은 변하지 않았을까요?

 

JSON.stringfy(wes)를 확인해보면 문자열로 인식되어있기 때문에 변하지 않습니다.

 

 

++ 내가 생각해본 방법

 

const wes = {
  name : 'Wes',
  age: 100,
  social: {
    twitter: '@wesbos',
    facebook: 'wesbos.devloper'
  }
};

console.log(wes);

const devSocial = Object.assign({}, wes.social);
const dev = Object.assign({}, wes, {social: devSocial});

 

 

더 자세하게 알기 위해서는 Javascript의 Deep copy와 Shallow copy에 대해 알아야 합니다.

 

 

JavaScript30 강의를 보고 공부한 글입니다. (https://javascript30.com/)

'JavaScript30 Challenge' 카테고리의 다른 글

[JavaScript30] Day 16  (0) 2020.07.20
[JavaScript30] Day 15  (0) 2020.06.25
[JavaScript30] Day 13  (0) 2020.06.08
[JavaScript30] Day 12  (0) 2020.05.14
[JavaScript30] Day 11  (0) 2020.05.04