Dev/JavaScript30

14. JavaScript Reference VS Copying ( JavaScript30 )

takeU 2021. 7. 9. 13:39
반응형

JavaScript References VS Copying

목표

자바스크립트 참조와 복사의 차이에 대해서 공부

 

기본 코드

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>JS Reference VS Copy</title>
</head>
<body>
  <script>
        const players = ['Wes', 'Sarah', 'Ryan', 'Poppy'];
  </script>
</body>
</html>

기본 코드가 전부 주석으로 필요한 코드만 남기고 다 지웠음

 

과정

  1. 변수 설정
  2. 이미지를 날아오게 할 함수 생성
  3. 함수 호출

 

코드 분석

1. 문자열, 숫자열, 불린일 때 변수 선언 및 변경

// start with strings, numbers and booleans
let age = 100;
let age2 = age;

console.log(age, age2); // 100, 100 출력
age = 200;
console.log(age, age2); // 200, 100 출력

문자열, 숫자열, 불린에서는 위와 같이 선언했던 변수에 다른 값을 넣으면 변경되어 출력된다.

2. 배열일 때 변수 선언 및 변경

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

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

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

분명히 team[3]으로 team의 배열만 바꾸고 싶었는데 결과는 players도 함께 바뀌게 된다.
즉, team은 players의 주소를 참조한다.(reference)

이를 해결하기 위해서는 아래와 같이 사용할 수 있다.

//해결방법 1 - slice()
const team2 = players.slice();

//해결방법 2 - concat()
const team3 = [].concat(players);

//해결방법 3 - [...](spread operator)
const team4 = [...players];

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

위의 네가지의 방법으로 새로운 배열을 만들어(copy) 기존 배열의 변경 없이 따로 값을 변경할 수 있다.

3. 객체일 때 변수 선언 및 변경

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

console.log(person) // {name: 'Wes Bos', age: 80, number: 99}

배열과 마찬가지로 원래의 객체 또한 변경이 된다.
이를 해결하기 위해서는 아래와 같이 사용 할 수 있다.

//해결방법 1 - Object.assign({}, 참조객체, 추가할값)
const cap2 = Object.assign({}, person, { number: 99, age: 12 });

//해결방법 2 - {...}
const cap3 = {...person};

위의 방법으로는 아래 코드에서 social안의 twitter내용을 변경할 수 없기 때문에 JSON을 아래와 같이 사용

const wes = {
  name: 'Wes',
  age: 100,
  social: {
    twitter: '@wesbos',
    facebook: 'wesbos.developer'
  }
};
const dev2 = JSON.parse(JSON.stringify(wes));
dev2.social.twitter = 'Hi'