JavaScript - 전개연산자(spread)와 와 나머지 매개변수(rest)

BigbrotherShin·2020년 2월 6일
1

JavaScript

목록 보기
3/17
post-thumbnail

전개 연산자와 나머지 매개변수

상당수의 자바스크립트 내장 함수는 임의의 수의 인수를 허용합니다.

예시:

Math.max(arg1, arg2, ..., argN) – 인수 중 가장 큰 수를 반환합니다.
Object.assign(dest, src1, ..., srcN) – src1..N의 프로퍼티를 dest로 복사합니다.
기타 등등

이번 챕터에서는 이렇게 임의의 수의 인수를 받는 방법에 대해 알아보겠습니다. 또한 함수의 매개변수에 배열을 전달하는 방법에 대해서도 알아보겠습니다.

전개 연산자 ... (spread 문법)

기존의 것을 건들이지 않고, 새로운 객체를 만들 때 유용함.
이 문법을 사용하면, 객체 혹은 배열을 펼칠수있습니다.

지금까지 매개변수 리스트를 배열로 가져오는 방법에 대해 살펴보았습니다.

그런데 개발을 하다 보면 반대되는 기능이 필요할 때가 생깁니다. 배열을 통째로 매개변수에 넘겨주는 것 같이 말이죠.

예시를 통해 이런 경우를 살펴봅시다. 내장 함수 Math.max는 인수로 받은 숫자 중 가장 큰 숫자를 반환합니다.

alert( Math.max(3, 5, 1) ); // 5

배열 [3, 5, 1]이 있는데, 이 배열에 Math.max를 호출할 수 있을까요?

아무런 조작 없이 배열을 “있는 그대로” Math.max에 넘기면 원하는 대로 동작하지 않습니다. Math.max는 배열이 아닌 숫자형 인수를 받기 때문입니다.

let arr = [3, 5, 1];

alert( Math.max(arr) ); // NaN

Math.max (arr [0], arr [1], arr [2]) 처럼 숫자를 수동으로 나열할 수도 있는데 배열 길이를 알 수 없기 때문에 이마저도 불가능합니다. 스크립트가 돌아갈 때 배열 내 요소가 아주 많을 수도, 아예 없을 수도 있죠. 수동으로 이걸 다 처리하다 보면 코드가 지저분해집니다.

전개 연산자(spread operator)는 이럴 때 사용하기 위해 만들어졌습니다. 전개 연산자는 ...를 사용하기 때문에 나머지 매개변수와 비슷해 보이지만, 나머지 매개변수와 반대의 역할을 해주죠.

함수를 호출할 때 ... arr를 사용하면, 반복 가능한 객체 arr이 인수 리스트로 "확장"됩니다.

Math.max를 사용한 예시로 다시 돌아가 봅시다.

let arr = [3, 5, 1];

alert( Math.max(...arr) ); // 5 (전개 연산자가 배열을 인수 리스트 바꿔주었습니다.)

아래와 같이 이터러블 여러 개를 전달하는 것도 가능합니다.

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(...arr1, ...arr2) ); // 8

전개 연산자를 평범한 값과 혼합해 사용하는 것도 가능하죠.

let arr1 = [1, -2, 3, 4];
let arr2 = [8, 3, -8, 1];

alert( Math.max(1, ...arr1, 2, ...arr2, 25) ); // 25

전개 연산자를 활용해 배열을 병합할 수도 있습니다.

let arr = [3, 5, 1];
let arr2 = [8, 9, 15];

let merged = [0, ...arr, 2, ...arr2];

alert(merged); // 0,3,5,1,2,8,9,15 (0, arr, 2, arr2 순서로 합쳐집니다.)

위 예시에선 배열을 대상으로 어떻게 전개 연산자가 동작하는지 보여줬는데 배열이 아니더라도 이터러블이라면 전개 연산자를 사용할 수 있습니다.

객체에서의 spread

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

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

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

위 코드의 핵심은 기존의 객체는 수정하지 않고 새로운 객체를 만드는 것인데요.
이 때 spread 문법을 사용하면 다음과 같이 작성 할 수 있습니다.

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

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

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

나머지 매개변수 ... (rest 문법)

함수의 정의 방법과 상관없이 함수를 호출할 때 넘겨주는 인수의 개수엔 제약이 없습니다.

아래와 같이 말이죠.

function sum(a, b) {
  return a + b;
}

alert( sum(1, 2, 3, 4, 5) );

함수를 정의할 땐 인수를 두 개만 받을 수 있다고 정의했고, 실제 함수를 호출할 땐 이보다 더 많은 인수를 전달하였는데 에러가 발생하지 않습니다. 하지만 반환 값은 당연히 처음 두 개의 인수만을 이용해 계산되죠.

마침표 세 개 ... 뒤에 배열 이름을 적어준 후 함수 선언부의 매개변수 자리에 넣어주면 나머지 매개변수를 배열에 넣어줄 수 있습니다. 마침표 세 개 ...가 의미하는 바는 "나머지 매개변수들을 한데 모아 배열에 집어넣어라"라는 의미를 갖죠.

아래 예시에선 모든 인수가 배열 args에 모입니다.

function sumAll(...args) { // args는 배열의 이름입니다.
  let sum = 0;

  for (let arg of args) sum += arg;

  return sum;
}

alert( sumAll(1) ); // 1
alert( sumAll(1, 2) ); // 3
alert( sumAll(1, 2, 3) ); // 6

앞부분의 매개변수는 변수로, 남아있는 매개변수들은 배열로 모을 수도 있습니다.

아래 예시에선 처음 두 인수는 변수에, 나머지 인수는 titles이라는 배열에 할당됩니다.

function showName(firstName, lastName, ...titles) {
  alert( firstName + ' ' + lastName ); // Julius Caesar

  // 나머지 인수들은 배열 titles에 할당됩니다.
  // titles = ["Consul", "Imperator"]
  alert( titles[0] ); // Consul
  alert( titles[1] ); // Imperator
  alert( titles.length ); // 2
}

showName("Julius", "Caesar", "Consul", "Imperator");

나머지 매개변수는 항상 마지막에 있어야 합니다.

나머지 매개변수는 “남아있는” 인수 모두를 모으는 역할을 하므로 아래 예시에선 에러가 발생합니다.

function f(arg1, ...rest, arg2) { // ...rest 후에 arg2가 있으면 안 됩니다.
  // 에러
}

...rest는 항상 마지막에 있어야 합니다.

객체에서의 rest

객체에서의 예시를 알아볼까요?

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

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

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

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

요약

"..."는 전개 연산자나머지 매개변수로 사용됩니다.

전개 연산자와 나머지 매개변수는 아래의 방법으로 구분할 수 있습니다.

  • ...이 함수 호출 시 사용되면 배열을 목록으로 확장해주는 "전개 연산자"입니다.
  • ...이 함수 매개변수의 끝에 있으면 인수 목록의 나머지를 배열로 모아주는 "나머지 매개변수"입니다.

사용 패턴:

  • 인수 개수에 제한이 없는 함수를 만들 때 나머지 매개변수를 사용합니다.
  • 많은 수의 인수를 받는 함수에 배열을 전달할 때 전개 연산자를 사용합니다.
  • 둘을 함께 사용하면 매개변수 목록과 배열 간 전환을 쉽게 할 수 있습니다.

출처: 나머지 매개변수와 전개 연산자
07. spread 와 rest 문법 · GitBook

profile
JavaScript, Node.js 그리고 React를 배우는

2개의 댓글

comment-user-thumbnail
2020년 8월 5일

안녕하세요 혹시 const { color, …rest } = purpleCuteSlime; 이부분에서
rest 에 color 를 제외한 나머지가 들어가야 할거 같은데
내용에 name 을 제외한으로 되어있어서 한번 확인 부탁드립니다.

답글 달기
comment-user-thumbnail
2023년 6월 19일

객체에서의 rest
에서 color에는 purpleCuteSlime.color이 들어 있고
rest는 나머지 name, attribute가 들어 있네요~

자바스크립트 처음 배우는데 잘 보고 갑니다~ 감사~

답글 달기