ES6에서 추가된 기능으로 Spread Syntax, Rest Parameter 등이 있다.
Spread Syntax(전개 구문)와 Rest Parameter(나머지 변수, 국내에서는 주로 rest 파라미터로 통용)는 둘 다 점 세개(...)로 표현할 수 있지만, 그 쓰임새는 완전히 다르다.
Spread 문법(Spread Syntax)은 대상을 개별 요소로 분리하며, Spread 문법의 대상은 이터러블이어야 한다.
배열을 분해하여 배열의 각 요소를 파라미터에 전달하고 싶은 경우, Function.prototype.apply를 사용하는 것이 일반적이다.
ES6의 Spread 문법을 사용한 배열을 인수로 함수에 전달하면 배열의 요소를 분해하여 순차적으로 파라미터에 할당한다.
Rest 파라미터는 Spread 문법을 사용하여 파라미터를 정의한 것을 의미한다.
(형태가 동일하여 혼동할 수 있으므로 주의가 필요함)
Rest 파라미터는 반드시 마지막 파라미터여야 하지만, Spread 문법을 사용한 인수는 자유롭게 사용할 수 있다.
Spread 문법이 도입되면서 concat(), push(), splice() 등을 사용하지 않고 훨씬 더 간결하게 배열을 합칠 수 있게 되었다.
ES5에서 사용하던 기존의 방식과 ES6에서 사용하는 Spread 문법을 비교하여 살펴보자.
기존에 concat을 사용하던 방식
push
splice
copy
ES5에서 기존 배열을 복사하기 위해서는 slice 메소드를 사용한다.
Spread 문법을 사용하면 보다 간편하게 배열을 복사할 수 있다.
이때 원본 배열의 각 요소를 얕은 복사(shallow copy)하여 새로운 복사본을 생성한다.
Spread 문법과 Object.assign은 원본을 Shallow copy한다. Deep copy를 위해서는 lodash의 deepClone을 사용한다.
다차원 배열을 복사할 때 주의할 점 :
다차원 배열을 복사할 때는 조심해야 한다. 복사하는 요소가 배열인 경우, 그 주소를 복사한다.
즉, 배열 형태의 요소는 깊은 복사를 한다.
newNum[1]은 oldNum[1]이 가진 [2, 3] 배열의 주소값을 가지게 되므로 oldNum[1]과 newNum[1]은 같은 배열을 참조하게 된다. 따라서 newNum[1]이 참조하는 배열의 요소를 변경하게 되면, oldNum[1]도 같은 배열을 참조하기 때문에 영향을 미치게 된다.
따라서 다차원 배열을 복사할 때는 배열 요소가 깊은 복사 된다.
ECMAScript2018부터 객체에도 Spread Syntax를 사용할 수 있게 되었다. 즉, 키-값 쌍을 확장할 수 있다.
Spread Syntax를 이용해 다수의 객체를 복사하는 경우, 키가 겹치면 기존 키 값을 덮어쓴다.
비슷한 작업을 Object.assign() 메서드를 이용해 실행할 수도 있다.
Object.assign(target_obj, source_obj)
target_obj 객체에 source_obj의 속성을 복사하고, 복사된 target_obj를 리턴한다.
다만, Spread Syntax를 사용하는 경우 원본 객체가 변하지 않지만, Object.assign() 메서드를 사용하면 원본 객체가 변한다.
주의할 점 : 객체 Spread Syntax는 객체에서만 가능하다.
Rest 파라미터(Rest Parameter, 나머지 매개변수)는 매개변수 이름 앞에 ...을 붙여서 정의한 매개변수로, 함수에 전달된 인수들의 목록을 배열로 전달받는다.
함수에 전달된 인수들은 순차적으로 파라미터와 Rest 파라미터에 할당된다.
Rest 파라미터는 먼저 선언된 파라미터에 할당된 인수를 제외한 나머지 인수들이 모두 배열에 담겨 할당된다.
따라서 Rest 파라미터는 반드시 마지막 파라미터여야 한다.
Rest 파라미터는 함수 객체의 length 프로퍼티에 영향을 주지 않는다.
기존 JavaScript에서는 함수의 매개변수로 배열을 받으려면 arguments라는 유사 배열을 활용했다. 하지만 ES6의 Rest Parameter를 이용하면 함수의 매개변수들을 쉽게 배열로 만들 수 있다.
(단, Rest Parameter는 항상 마지막에 위치해야 한다.)