JavaScript & TypeScript

[JS] Spread, Rest, Destructing

반응형

Spread와 Rest 문법은 굉장히 비슷한데.

기능에 대한 설명만 주구장창 표현을 하지 구별하는 명확한 차이에 대한 설명이 없어서 복잡했습니다.

제가 생각하는 공통점은 ... 을 앞에 붙이는 것이고.

 

차이점은 먼저 Spread는 배열하고자 하는 어느 변수를 사용해도 상관 없는 것입니다.

Rest는 ...rest를 사용하지만 함수의 파라미터(매개변수)가 존재한다면 (...변수)를 사용해야합니다

그리고 ...rest를 배열이나 객체 끝에 사용하고 그 뒤에는 더 이상 다른 내용이 들어 와서는 안됩니다. rest라는 단어의 뜻을 이해하면 쉽게 이해가 됩니다.

 

정확한 것은 아니지만 이렇게 개념을 잡고 해당 내용을 이해할 때에 도움이 되었습니다.

 

 

1. Spread 문법

객체나, 배열에서 사용 가능 합니다. 주로 배열을 풀어서 인자로 전달하거나, 배열을 풀어서 각각의 요소로 넣을 때에 사용합니다.

그래서 홈페이지 만들때에 정보를 일일이 넣지 않아도 되어서 보안에 도움이 된다고 동기분들이 설명해 주셨습니다.

function sum(x, y, z) {
  return x + y + z;
}

const numbers = [1, 2, 3];

sum(...numbers) // 6

기존의 것을 건들이지 않고, 새로운 객체를 만든다는 것. 이러한 상황에 사용 할 수 있는 유용한 문법이 spread 입니다.

 

const animals = ['개', '고양이', '참새'];
const anotherAnimals = [...animals, '비둘기'];
console.log(animals);  //  ['개', '고양이', '참새']
console.log(anotherAnimals); // ['개', '고양이', '참새', '비둘기']

 

 

2. Rest 문법

 

파라미터를 배열의 형태로 받아서 사용할 수 있습니다. 파라미터 개수가 가변적일 때 유용합니다.

함수에서 값을 읽을때, 그 값들은 파라미터라고 부릅니다. 그리고 함수에서 값을 넣어줄 때, 그 값들은 인자라고 부릅니다.

rest는 생김새는 spread 랑 비슷한데, 역할이 매우 다릅니다.

rest는 객체, 배열, 그리고 함수의 파라미터에서 사용이 가능합니다.

 

Rest 함수

function sum(...abc) {
  return abc.reduce((acc, current) => acc + current, 0);
}

const result = sum(1, 2, 3, 4, 5, 6);
console.log(result); // 21

 

Rest 객체

const purpleCuteSlime = {
  name: '슬라임',
  attribute: 'cute',
  color: 'purple'
};
const { color, ...rest } = purpleCuteSlime;



console.log(color);  // 'purple'

console.log(rest);  // {attribute: 'cute', color: 'purple'};

console.log({color, ...rest});  
//{name: '슬라임', attribute: 'cute', color: 'purple'};

 

Rest 배열

const numbers = [0, 1, 2, 3, 4, 5, 6];

const [one, ...rest] = numbers;

console.log(one);  // '0'
console.log(rest); // [1, 2, 3, 4, 5, 6]

one은 string 타입 '0', rest는 배열 [1, 2, 3, 4, 5, 6]이 출력

 

아래의 경우는 사용이 불가능 합니다.

rest라는 단어가 나머지라는 뜻을 가지고 있는데 맨 앞에 나머지를 전부 넣어버리는 것이 되니 last에 들어갈 값이 없습니다.

const [...rest, last] = numbers;

 

 

3. 구조 분해 (Destructing)

 

구조 분해 할당은 Spread 문법을 이용하여 값을 해체한 후, 개별 값을 변수에 새로 할당하는 과정

 

배열

const [a, b, ...rest] = [10, 20, 30, 40, 50];

객체

const {a, b, ...rest} = {a: 10, b: 20, c: 30, d: 40}

함수

function whois({displayName: displayName, fullName: {firstName: name}}){
  console.log(displayName + " is " + name);
}

let user = {
  id: 42,
  displayName: "jdoe",
  fullName: {
      firstName: "John",
      lastName: "Doe"
  }
};

whois(user) // jdoe is John

 

구조분해는 분해해서 개별 변수에 재할당 하는 개념인데 재할당이 복사라는 개념이고 어떻게 재할당 되느냐에 따라 다른 것 같다.

얕은 복사(Shallow copy) 깊은 복사(Depth copy) 

관련 개념이 등장하였다. 동기분들끼리 굉장히 있어보이는 답변을 해놓지만 그건 아는사람들끼리라 쉬어보일 수 있다고 생각 하였다.

 

얕은 복사는 이란성 쌍둥이 

깊은 복사는 일란성 쌍둥이 같은 개념인 것 같다.

 

복사는 하였지만 완전한 복사가 아니기에 앝고, 깊음을 나타내었고

일란성이든 이란성이든 각각의 쌍둥이는 다른 사람이고, 이름도 다른것 처럼 결국 완전한 같음(equal)은 아니라는 점.

 

그리고 이란성은 모습이 다르고, 일란성은 모습이 거의 똑같기 때문에

얕은 복사는 객체나 배열안의 모습이 다르고, 깊은 복사는 내용이 완전 똑같지만 결국 같은 배열, 객체가 아니라는 점이다.

 

즉, 완전한 복사가 아니지만 그 복사의 형태가 어떠하냐에 따라 나타내는 것 같다.

 

  1. 단순복제는 완전히 동일한 객체,
  2. 얕은복사(shallow copy)는 복합객체(껍데기)만 복사, 그 내용은 동일한 객체
  3. 깊은복사(deep copy)는 복합객체 복사 + 그 내용도 재귀적으로 복사

 

아래는 크루분들과 동기분들이 한 내용을 간추렸는데 다들 햇갈려하고 어려워 하는 부분이긴 한 것 같다.

마지막 문장은 기억을 해두면 좋을 것 같다.

 

- 배열은 깊은 복사가 가능하지만, 부분적으로 효과적이지 못하고

- 오락가락하는(..) 룰을 외우고 있는 것보다, 안전하게 사용하는 것을 추천드립니다: 값복사만...

- 복사본이 원본을 교체할 수 있다는 그 가능성 자체로부터 그것은 결국 얕은복사로 생각해버리는 것이 위험을 방지하는 일

- depth가 2 이상인 경우에 얕은 복사가 일어나면 처음 입력된 key에 해당하는 value만 남는것

 

<깊은 복사, 얕은 복사 관련 블로그 내용>

https://helloinyong.tistory.com/267

https://blueshw.github.io/2016/01/20/shallow-copy-deep-copy/

 

오늘 코드스테이츠 방식은 코드 보는게 이해 더 잘된다고 코드만 던져놓고 설명은 별로여서 짜증이 엄청나서 이해하는데 애를 먹었다. 오히려 검색해서 찾아 볼 때에 더 햇갈리게 만들었다.

오늘 페어와 진행하는 과제를 진행해보면서 그때 그때 익혔다. 이걸 노린거면 진짜 코드스테이츠는 천재다.

반응형

'JavaScript & TypeScript' 카테고리의 다른 글

[JS] DOM  (6) 2021.06.06
[JS] 복습(과제) 정리  (0) 2021.06.01
[JS] 스코프, 클로저  (0) 2021.05.29
[JS] 객체  (1) 2021.05.27
[JS] 배열  (0) 2021.05.25