WEB/Javascript

[JAVASCRIPT.INFO] 6.2 나머지 매개변수와 스프레드 문법

dev-olive 2023. 1. 19. 20:42

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 (참조가 다름)