JavaScript 나머지 매개변수와 스프레드 문법

Leejunyoung·2022년 8월 26일
1

JavaScript

목록 보기
44/49

나머지 매개변수와 스프레드 문법

상당수의 자바스크립트 내장 함수는 인수의 개수에 제약을 두지 않는다.
  • Math.max(arg1, arg2, ..., argN) – 인수 중 가장 큰 수를 반환한다.
  • Object.assign(dest, src1, ..., srcN) – src1..N의 프로퍼티를 dest로 복사한다.
  • 기타 등등
  • 이번엔 이렇게 임의의(정해지지 않은) 수의 인수를 받는 방법에 대해 알아보자. 또한 함수의 매개 변수에 배열을 전달하는 방법에 대해서도 알아보자.


    나머지 매개변수 ...

    함수 정의 방법과 상관없이 함수에 넘겨주는 인수의 개수엔 제약이 없다.

    함수를 정의할 땐 인수를 두 개만 받도록 하고, 실제 함수를 호출할 땐 이보다 더 많은 '여분의' 인수를 전달했지만, 에러가 발생하지 않았다. 다만 반환 값은 처음 두 개의 인수만을 사용해 계산된다.

    이렇게 여분의 매개변수는 그 값들을 담을 배열 이름을 마침표 세 개 ... 뒤에 붙여주면 함수 선언부에 포함시킬 수 있다. 이때 마침표 세 개 ...는 "남아있는 매개변수들을 한데 모아 배열에 집어넣어라"는 것을 의미한다.

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

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

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


    arguments 객체

    유사 배열 객체(array-like object)인 arguments를 사용하면 인덱스를 사용해 인수에 접근할 수 있다.

    나머지 매개변수는 비교적 최신에 나온 문법이다. 나머지 매개변수가 나오기 이전엔 함수의 인수 전체를 얻어내는 방법이 arguments를 사용하는 것밖에 없었다. 물론 지금도 arguments를 사용할 수 있다. 오래된 코드를 보다보면 arguments를 만나게 된다.

    arguments는 유사 배열 객체이면서 이터러블(반복 가능한) 객체이다. 어쨋든 배열은 아니다.
    따라서 배열 메서드를 사용할 수 없다는 단점이 있다. arguments.map (...)을 호출할 수 없다.

    여기에 더하여 arguments는 인수 전체를 담기 때문에 나머지 매개변수처럼 인수의 일부만 사용할 수 없다는 단점도 있다.

    따라서 배열 메서드를 사용하거나 인수 일부만 사용할 때는 나머지 매개변수를 사용하는 게 좋다.


    스프레드 문법

    지금까지 매개변수 목록을 배열로 가져오는 방법에 대해 살펴보았다.

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

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

    배열 [3, 5, 1]이 있고, 이 배열을 대상으로 Math.max를 호출하고 싶다고 가정해보자.

    아무런 조작 없이 배열을 '있는 그대로' Math.max에 넘기면 원하는 대로 동작하지 않는다.
    Math.max는 배열이 아닌 숫자 목록을 인수로 받기 때문이다.

    Math.max(arr[0], arr[1], arr[2]) 처럼 배열 요소를 수동으로 나열하는 방법도 있긴한데, 배열 길이를 알 수 없을 때는 이마저도 불가능하다. 스크립트가 돌아갈 때 실제 넘어오는 배열의 길이는 아주 길 수도 있고, 아예 빈 배열일 수도 있기 때문이다. 수동으로 이걸 다 처리하다 보면 코드가 지저분해진다.

    스프레드 문법(spread syntax, 전개 문법)은 이럴 때 사용하기 위해 만들어졌다. ...를 사용하기 때문에 나머지 매개변수와 비슷해 보이지만, 스프레드 문법은 나머지 매개변수와 반대되는 역할을 한다.

    함수를 호출할 때 ...arr를 사용하면, 이터러블 객체 arr인 인수 목록으로 '확장'된다.

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

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

    스프레드 문법을 평범한 값과 혼합해 사용하는 것도 가능하다.

    스프레드 문법은 배열을 합칠 때도 활용할 수 있다.

    앞선 예시들에선 '배열'을 대상으로 스프레드 문법이 어떻게 동작하는지 살펴보았다.
    그런데 배열이 아니더라도 이터러블 객체이면 스프레드 문법을 사용할 수 있다.

    스프레드 문법을 사용해 문자열을 문자 배열로 변환 시켜보자.

    스프레드 문법은 for..of와 같은 방식으로 내부에서 이터레이터(iterator, 반복자)를 사용해 요소를 수집한다.

    문자열에 for..of를 사용하면 문자열을 구성하는 문자가 반환된다. ...str도 H,e,l,l,o 가 되는데, 이 문자 목록은 배열 초기자(array initializer) [...str]로 전달된다.

    메서드 Array.from은 이터러블 객체인 문자열을 배열로 바꿔주기 때문에 Array.from을 사용해도 동일한 작업을 할 수 있다.

    [...str]과 동일한 결과가 출력되는 것을 확인할 수 있다.

    그런데 Array.from(obj)와 [...ogj]는 다음과 같은 미묘한 차이가 있다.

  • Array.from은 유사 배열 객체와 이터러블 객체 둘 다에 사용할 수 있다.
  • 스프레드 문법은 이터러블 객체에만 사용할 수 있다.
  • 이런 이유 때문에 무언가를 배열로 바꿀 때는 스프레드 문법보다. Array.from이 보편적으로 사용된다.


    배열과 객체의 복사본 만들기

    참조에 의한 객체 복사 챕터에서 Object.assign()을 사용해 객체를 복사한 예시를 떠올려보자.

    Object.assign() 말고도 스프레드 문법을 사용하면 배열과 객체를 복사할 수 있다.

    이번엔 객체를 복사하는 예시를 살펴보자.

    이렇게 스프레드 문법을 사용하면 let objCopy = Object.assign({}, obj);, let arrCopy = Object.assign([], arr); 보다 더 짧은 코드로 배열이나 객체를 복사할 수 있어서 사람들은 이 방법을 선호하는 편이라고 한다.

    profile
    안녕하세요

    0개의 댓글