rest parameter와 spread syntax는 형태가 (...)로 같아서 자칫하면 헷갈릴 수 있다. 그러나 두 역할은 완전히 다르다.
rest parameter는 개별의 요소들을 하나의 배열로 묶기 위해 사용하는 반면에 spread syntax는 iterable한 요소를 펼치기 위해 사용하는 문법이다.
rest parameter : 개별의 요소들을 하나로 묶기 위해 사용
spread syntax : 하나의 요소를 개별의 요소들로 펼치기 위해 사용
rest parameter는 매개변수 앞에 점 ...을 붙여서 정의한 매개변수를 의미한다. 묶인 요소들의 타입은 '배열'로 출력된다.
function myFunc(...rest) { console.log(rest); } myFunc(1, 2, 3, 4, 5); // [1, 2, 3, 4, 5]
가장 간단한 예시이다. myFunc라는 함수를 호출할 때 5개의 전달인자를 사용했다. 함수 myFunc에서는 rest parameter를 이용해서 5개의 전달인자를 한꺼번에 받을 수 있다. 출력된 결과를 보면 모든 요소들은 배열 안에 담겨있다.
물론 rest parameter로만 받을 수 있는 것은 아니다.
function myFunc(first, second, ...rest) { console.log(first); console.log(second); console.log(...rest); } myFunc(1, 2, 3, 4, 5); // 1 // 2 // [3, 4, 5]
다만, 여기서 주의해야 할 점이 한가지 있다. rest parameter는 매개변수들 중에서 가장 뒤에 들어가야 한다.
function myFunc2(...rest, first) { console.log(rest); console.log(first); } myFunc2(1, 2, 3, 4, 5); // Uncaught SyntaxError: Rest parameter must be last formal parameter
파라미터의 순서가 잘못 되었기 때문에 에러가 발생하였다.
spead syntax를 이용하면 배열, 문자열, 객체 등 Iterable Object를 각각의 요소로 펼칠 수 있다.
spread syntax는 다음과 같은 세 가지 상황에서 사용된다.
1) 함수 호출문
함수의 전달인자에서 사용하는 것이다.
ES6 문법의 도입 전에는 직접 하나씩 넣어주거나, apply를 이용해야 했지만 spread syntax를 이용하면 손쉽게 넣어줄 수 있다.
function myFunc(a, b, c) { return a + b + c; } var args = [10, 30, 20]; myFunc(args); // 10,30,20,undefinedundefined myFunc(...args); // 60
2) 배열
[배열의 결합]
ES6 문법 이전 => concat 사용
var a = [1, 2, 3]; var b = [10, 20, 30]; var result = a.concat(b); // [1, 2, 3, 10, 20, 30]
ES6 문법 => spread syntax 이용
var a = [1, 2, 3]; var b = [10, 20, 30]; var c = [40, 50, 60]; var result = [...a, ...b, ...c]; // [1, 2, 3, 10, 20, 30, 40, 50, 60]
[배열의 복사]
이전 => slice 사용
var a = [1, 2, 3]; var b = a.slice(); // [1, 2, 3]
이후 => spread syntax 사용
var a = [1, 2, 3]; var b = [...a]; // [1, 2, 3] var c = ...a; // Uncaught SyntaxError: Unexpected token '...'
3) 객체
[객체의 복사]
이전 => assign() 사용
var obj1 = {a: 1, b: 2}; var obj2 = {b: 4, c: 5}; var result = Object.assign(obj1, obj2); // { a: 1, b: 4, c: 5 }
이후 => spread syntax 사용
var obj1 = {a: 1, b: 2}; var obj2 = {b: 4, c: 5}; var result = {...obj1, ...obj2}; // { a: 1, b: 4, c: 5 }