[JAVASCRIPT.INFO] 6.2 나머지 매개변수와 스프레드 문법
6.2 나머지 매개변수와 스프레드 문법
임의의(정해지지 않은) 수의 인수를 받는 방법
나머지 매개변수 ...
함수를 정의할 땐 인수를 두 개만 받도록 하고, 실제 함수를 호출할 땐 이보다 더 많은 '여분의' 인수를 전달해도 에러가 발생하지 않는다. 다만 반환 값은 처음 두 개의 인수만을 사용해 계산된다.
이렇게 여분의 매개변수는 그 값들을 담을 배열 이름을 마침표 세 개 ...
뒤에 붙여주면 함수 선언부에 포함시킬 수 있다.
function sumAll(...arg) {
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
function showName(firstName, lastName, ...title){
alert(firstName + ' ' + lastName); // Bora Lee
alert(title[0]); // Software Engineer
alert(title[1]); // Researcher
alert(title.length); // 2
}
showName("Bora", "Lee", "Software Engineer", "Researcher");
나머지 매개변수는 항상 마지막에 있어야 한다.
arguments 객체
유사 배열 객체인 arguments
를 사용하면 인덱스를 사용해 인수에 접근할 수 있다.
function showName() {
alert( arguments.length );
alert( arguments[0] );
alert( arguments[1] );
}
showName("Bora", "Lee"); // 2, Bora, Lee
showName("Bora"); // 1, Bora, undefined(2번째 인수 없음)
나머지 매개변수가 나오기 이전엔 함수의 인수 전체를 얻어내는 방법이 arguments
를 사용하는 것 밖에 없었다.
arguments
는 유사 배열 객체이면서 이터러블 객체이다. (배열은 아님) 따라서 배열 메서드를 사용할 수 없다는 단점이 있다. arguemtns.map(...)
을 호출 할 수 없음
또한 arguments
는 인수 전체를 담기 때문에 나머지 매개변수처럼 인수의 일부만 사용할 수 없다.
화살표 함수는 arguments
객체를 지원하지 않는다.
화살표 함수에서 arguments
객체에 접근하면, 외부에 있는 '일반' 함수의 arguments 객체를 가죠온다.
function f() {
let showArg = () => alert(arguments[0]);
showArg();
}
f(1); // 1
스프레드 문법
배열을 통째로 매개변수에 넘겨주는 것과 같은 기능이 필요할 경우가 있다.
Math.max(3,5,1); // 5
let arr = [3,5,1];
Math.max(arr); // NaN
Math.max
는 배열이 아닌 숫자 목록을 인수로 받기 때문에 오류가 NaN
이 출력된다.
스프레드 문법은 ...
을 사용하기 때문에 나머지 매개변수와 비슷해보이지만 반대되는 역할을 한다. 함수를 호출할 때 ...arr
를 사용하면, 이터러블 객체 arr
이 인수 목록으로 '확장'된다.
let arr1 = [1,-2,3,4];
let arr2 = [8,3,-8,1];
Math.max(...arr1, ...arr2); // 8
let arr = [3,5,1];
let arr2 = [8,9,16];
let merged = [0, ...arr, 2, ...arr2];
// 0, 3, 5, 1, 2, 8, 9, 16
배열이 아니더라도 이터러블 객체이면 스프레드 문법을 사용할 수 있다.
let str = "Hello";
[...str] // H, e, l, l, o
Array.from(obj)
와 [...obj]
의 차이점
Array.from
은 유사 배열 객체와 이터러블 객체 둘 다 사용 가능[...obj]
는 이터러블 객체에만 사용 가능
이런 이유로 배열로 변경할 경우 스프레드 문법보다 Array.from
이 보편적으로 사용된다.
배열과 객체의 복사본 만들기
let arr = [1,2,3];
let arrCopy = [...arr];
// 배열을 펼쳐서 각 요소를 분리 후, 매개변수 목록으로 만든 다음에 매개변수 목록을 새로운 배열에 할당
JSON.stringify(arr) === JSON.stringify(arrCopy); // true
arr === arrCopy // false (참조가 다름)
let obj = {a: 1, b: 2, c: 3};
let objCopy = {...obj};
// 객체를 펼쳐서 각 요소를 분리 후, 매개변수 목록으로 만든 다음에 매개변수 목록을 새로운 객체에 할당
JSON.stringify(obj) === JSON.stringify(objCopy) // true
obj === objCopy // false (참조가 다름)