수학과의 좌충우돌 프로그래밍

[ES6] Spread and Rest 본문

웹프로그래밍/ES6

[ES6] Spread and Rest

ssung.k 2020. 1. 2. 04:58

Spread

Spread 는 변수를 가져와서 풀어헤치고 전개해주는 것을 말합니다.

unpacking 이라고 하죠.

Spread 를 사용하기 위해서 ... 을 사용합니다.

const fruits = ["apple", "banana", "melon", "strawberry"];

console.log(fruits);
console.log(...fruits);
// [ 'apple', 'banana', 'melon', 'strawberry' ]
// apple banana melon strawberry

 

이는 두 개의 array 를 합칠 때도 유용하게 사용합니다.

Spread 를 사용하지 않아도 배열을 합치는 방법은 많겠지만 코드 길이나 가독성 면에서 Spread 가 상당히 우수합니다.

const fruits = ["apple", "banana", "melon", "strawberry"];
const vegtables = ["carrot", "cucumber"]

console.log([...fruits, ...vegtables]);

// [ 'apple', 'banana', 'melon', 'strawberry', 'carrot', 'cucumber' ]

 

중간에 다른 값을 추가하더라도 문제 없습니다.

const fruits = ["apple", "banana", "melon", "strawberry"];
const vegtables = ["carrot", "cucumber"]

console.log([...fruits, "onion", ...vegtables]);
// [ 'apple', 'banana', 'melon', 'strawberry', 'onion', 'carrot', 'cucumber' ]

 

array 뿐 아니라 object 에서도 Spread 는 유효합니다.

const settings = {
  theme: "light"
}

const mySettings = {
  font_size: 24
}

console.log({...settings, ...mySettings});
// { theme: 'light', font_size: 24 }

 

Conditional Spread

다음과 같은 상황을 가정해보겠습니다.

fontSize 가 128 이하인 경우에는 이를 settings 에서 지정해주고 그렇지 않은 경우에는 지정을 하지 않는다고 해봅시다.

const settings = {
  theme: "light",
  fontSize: fontSize <= 128 ? fontSize : null
}

console.log(settings)
// fontSize = 30 인 경우
// { theme: 'light', fontSize: 30 }

// fontSize = 130 인 경우
// { theme: 'light', fontSize: null }

 

다음과 같이 삼항연산자를 통해서 구현했지만 key 값으로 fontSize 가 남아있습니다.

이 key 값 조차 없애고 싶으면 어떻게 해야할까요?

이를 optional object property 라고 합니다.

이 경우 Spread 가 유용하게 사용 될 수 있습니다.

우선 && 을 기준으로 앞 쪽은 원하는 조건입니다.

뒤 쪽은 조금 복잡하죠. 우선 ... 으로 Spread 하기 위해서 { } 로 감싸주었습니다.

중괄호 안에는 fontSize: fontSize 처럼 써야 할 것 같지만 한 번만 적어줘도 문제 없습니다.

shorthand 덕분이죠. shorthand가 뭔지 모른다면 아래 링크를 참조하시길 바랍니다.

https://ssungkang.tistory.com/entry/ES6-Destructuring

const settings = {
  theme: "light",
  ...(fontSize <= 128 && {fontSize})
}

console.log(settings)
// fontSize = 30 인 경우
// { theme: 'light', fontSize: 30 }

// fontSize = 130 인 경우
// { theme: 'light' }

 

 

Rest Parameters

위에서 살펴봤던 Spreadunpacking 을 해주었다면 Rest 는 반대로 packing 을 해줍니다.

자기소개를 하는 함수를 만들어봅시다. 이 경우 함수의 파라미터가 너무 많기 때문에 이를 다 기재해주는 것은 효율적이지 못합니다.

이런 경우 Rest 를 사용하며 한 번에 받을 수 있습니다.

const intro = (...info) => console.log(info);

intro("minsung", 25, "Seoul", "UOS", ["basketball", "go"]);
// [ 'minsung', 25, 'Seoul', 'UOS', [ 'basketball', 'go' ] ]

 

물론 필요한 부분은 따로 받고 나머지에 한하여 묶어서 받아줄 수도 있습니다.

const intro = (name,...rest) => {
  console.log(`my name is ${name}`);
  console.log(rest);
}

intro("minsung", 25, "Seoul", "UOS", ["basketball", "go"]);
// my name is minsung
// [ 25, 'Seoul', 'UOS', [ 'basketball', 'go' ] ]

 

Rest 로 값을 받으면 출력값의 공통점이 있습니다.

결과값이 array로 출력 된다는 것이죠.

 

Rest + Spread + Destructure

지금까지 배운 세 가지를 활용하면 많은 것을 할 수 있습니다.

한 번 알아보도록 하죠.

Destructure 가 익숙하지 않다면 아래를 참고해주세요.

https://ssungkang.tistory.com/entry/ES6-Destructuring

 

delete property

우선 첫 번째 예시는 user object 에 대해 익명으로 바꿔주고 싶습니다.

Destructure 를 이용해서 값을 받는데 이 때 Rest 를 통해 name 값과 나머지 값으로 받아준 후 나머지 값에 대해서만 반환해주었습니다.

이를 잘 활용하여 object 에 필요없는 key 들을 지울 수 있습니다.

const user = {
  name: "minsung",
  age: 25,
  city: "Seoul",
  school: "UOS"
}

const deleteName = ({name, ...rest}) => rest;

const AnonymousUser = deleteName(user);

console.log(AnonymousUser);
// { age: 25, city: 'Seoul', school: 'UOS' }

 

insert property

이번엔 필요한 key 를 넣어봅시다.

일반적으로 object 에 바로 넣게 되면 기존의 있는 값이 overwrite 될 수 있기 때문에 default value 를 설정하기가 까다롭습니다.

이 경우에도 DestructureRest 를 사용하면 해결 가능합니다.

7번째 줄의 ...rest 가 두 번 등장하는데 서로 다릅니다. 함수의 파리미터에 위치하는 첫 번째는 Rest 고 반환해주는 곳에 위치하는 두 번째는 Spread 에 해당됩니다.

let user = {
  name: "minsung",
  age: 25,
  city: "Seoul",
}

const insertSchool = ({school="UOS", ...rest}) => ({school, ...rest});

user = insertSchool(user);

console.log(user);
// { school: 'UOS', name: 'minsung', age: 25, city: 'Seoul' }

 

rename property

이번에는 key 값을 바꿔보도록 하겠습니다.

위와 동일한 논리로 전개됩니다.

다만 추가된 부분은 Destructure 의 rename 이 사용되었습니다.

let user = {
  name: "minsung",
  age: 25,
  city: "Seoul",
}

const rename = ({name:nickname, ...rest}) => ({nickname, ...rest});

user = rename(user);

console.log(user);
// { nickname: 'minsung', age: 25, city: 'Seoul' }

 

Comments