코딩하는망아치 2021. 4. 26. 21:40

이번에는 ES6에서 도입된 spread와 rest문법에 대해서 알아보자. 서로 완전히 다른 문법인데 은근히 좀 비슷하다.

 

spread

일단 spread 문법부터 알아봅시다. spread 라는 단어가 가지고 있는 의미는 펼치다. 퍼뜨리다 입니다. 이 문법을 사용하면, 객체 혹은 배열을 펼칠수 있다.

예를 들어서 다음과 같은 객체들이 있다고 가정해보자.

const slime = {
  name: '슬라임'
};

const cuteSlime = {
  name: '슬라임',
  attribute: 'cute'
};

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

console.log(slime);
console.log(cuteSlime);
console.log(purpleCuteSlime);

이 코드에서는 먼저 slime이라는 객체를 선언했다. 그리고 cuteSlime이 가지고 있는 값을 그대로 사용하였다.

기졵에 선언한 slime을 건들이지 않고 객체를 만들었는데요, 기존에 선언한 slime을 건들이지 않고 새로운 객체를 만들어서 slime이 가지고 있는 값을 그대로 사용하였다.

 

그 다음에는 purpleCuteSlime이라는 객체를 만들었는데요, 이 객체는 cuteSlime이 가지고 있는 속성을 그대로 사용하면서 추가적으로 color가 추가 되었다.

 

위 코드에서의 핵심은, 기존의 것을 건들이지 안ㅎ고, 새로운 객체를 만든다는 것인데 이러한 상황에 사용 할수 있는 유용한 문법이 spread이다.

 

아까 코드는 spread문법을 사용하면 다음과 같이 작성 할수 있다.

const slime = {
  name: '슬라임'
};

const cuteSlime = {
  ...slime,
  attribute: 'cute'
};

const purpleCuteSlime = {
  ...cuteSlime,
  color: 'purple'
};

console.log(slime);
console.log(cuteSlime);
console.log(purpleCuteSlime);

여기서 사용한 ... 문자가 바로 spread연산자이다.

spread연산자는배열에서도 사용 할 수 있다.

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

기존의 animals는 건드리지 않으면서, 새로운 anotherAnimals 배열에 animals가 가지고 있는 내용을 모두 집어넣고,'비둘기' 라는 항목을 추가적으로 넣었다.

배열에 spread연산자를 여러번 사용 할 수도 있다.

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

const spreadNumbers = [...numbers, 1000, ...numbers];
console.log(spreadNumbers); // [1, 2, 3, 4, 5, 1000, 1, 2, 3, 4, 5]

rest

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

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

객체에서의 rest

우선 객체에서의 예시를 알아보자.

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

const { color, ...rest } = purpleCuteSlime;
console.log(color);
console.log(rest);

rest 안에 name값을 제외한 값이 들어있다.

rest는 객체와 배열에서 사용 할때는 이렇게 비구조화 할당 문법과 함께 사용 된다. 주로 사용 할때는 위와 같이 rest라는 키워드를 사용하게 된다. 추출한 값의 이름이 꼭 rest일 필요는 없다.

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

const { color, ...cuteSlime } = purpleCuteSlime;
console.log(color);
console.log(cuteSlime);

이렇게 해도 무방하다.

이어서 attribute까지 없앤 새로운 객체를 만들고 싶다면 이렇게 해주면 된다.

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

const { color, ...cuteSlime } = purpleCuteSlime;
console.log(color);
console.log(cuteSlime);

const { attribute, ...slime } = cuteSlime;
console.log(attribute);
console.log(slime);

배열에서의 rest

다음 배열에서의 사용 예시를 알아보자.

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

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

console.log(one);
console.log(rest);

배열 비구조화 할당을 통하여 원하는 값을 밖으로 꺼내고, 나머지 값을 rest안에 넣었다.

이렇게 할수는 없다

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

const [..rest, last] = numbers;

함수 파라미터에서의 rest

rest를 함수 파라미터에서 사용 할 수도 있다. 예를 들어서 우리가 파라미터로 넣어준 모든 값들을 합해주는 함수를 만들어 주고 싶다고 가정해보자.

function sum(a, b, c, d, e, f, g) {
  let sum = 0;
  if (a) sum += a;
  if (b) sum += b;
  if (c) sum += c;
  if (d) sum += d;
  if (e) sum += e;
  if (f) sum += f;
  if (g) sum += g;
  return sum;
}

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

위에서의 sum함수는 7개의 파라미터를 받아오는데, 아래에서 사용 할때에는 6개만 넣어줬다.그러면, g 값이 undefined 가 되기 때문에 sum 에 더하는 과정에서 += undefined 를 하게 되면 결과는 NaN 이 되버린다.그렇기 때문에 함수에서 하나하나 유효한 값인지 확인을 해줬다.

함수의 파라미터가 몇개가 될 지 모르는 상황에서 rest파라미터를 사용하면 매우 유용하다. 코드를 다음과 같이 수정해보자.

function sum(...rest) {
  return rest;
}

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

result가 가르키고 있는 것은 함수에서 받아온 파라미터들로 이루어진 배열이다. 우리가 이제 파라미터들이 들어가 있는 배열을 받았으니 그냥 모두 더해주면 된다.

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

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

 

함수 인자와 spread

이번에는 다시 아까 배웠던 spread로 돌아와서 한가지를 더 배워보자. 함수의 인자와 spread인데, 만약 프로그래밍을 처음 배운다면 파라미터와 인자가 헷갈릴수 있다. 이에 대해서 간단하게 알아보자.

const myFunction(a) { // 여기서 a 는 파라미터
  console.log(a); // 여기서 a 는 인자
}

myFunction('hello world'); // 여기서 'hello world' 는 인자

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

인자가 무엇인지 이해를 했다면 이제 함수인자와 spread문법을 사용하는 것에 대하여 알아보자.

 

인자가 무엇인지 이해를 했다면 이제 함수인자와 spread문법을 사용하는것에 대해 알아보자. 우리가 방금 함수 파라미터와 rest를 사용한 것과 비슷한데, 반대의 역할이다. 우리가 배열안에 있는 원소들을 모두 파라미터로 넣어주고 싶다고 가정해보자.

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

const numbers = [1, 2, 3, 4, 5, 6];
const result = sum(
  numbers[0],
  numbers[1],
  numbers[2],
  numbers[3],
  numbers[4],
  numbers[5]
);
console.log(result);

굉장히 불편하다. 만약에 sum함수를 사용 할때 인자 부분에서 spread를 사용하면다음과 같이 표현이 가능하다.

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

const numbers = [1, 2, 3, 4, 5, 6];
const result = sum(...numbers);
console.log(result);

이렇게 spread와 rest를 잘 사용하면 앞으로 보기 깔끔한 코드를 작성하는 것에 큰 도움을 준다.