[자바스크립트 딥다이브] 35장 스프레드 문법

Bor·2022년 1월 11일
0

JS딥다이브

목록 보기
23/24

35장 스프레드 문법

ES6에서 도입된 스프레드 문법spread syntax(전개 문법)은 ... 하나로 뭉쳐 있는 여러 값들의 집합을 펼쳐서 개별적인 값들의 목록으로 만든다. 스프레드 문법을 사용할 수 있는 대상은 Array, String, Map, Set, DOM 컬렉션, arguments와 같이 for...of 문으로 순회할 수 있는 이터러블에 한정된다.

위의 1 2 3 은 값이 아니라 값들의 목록. 즉, 스프레드 문법의 결과는 값이 아니다. 이는 스프레드 문법 ...이 피연산자를 연산하여 값을 생성하는 연산자가 아님을 의미. 따라서 스프레드 문법의 결과는 변수에 할당할 수 없다.

이처럼 스프레드 문법의 결과물을 값으로 사용할 수 없고, 다음과 같이 쉼표로 구분한 값의 목록을 사용하는 문맥에서만 사용할 수 있다.

  • 함수 호출문의 인수 목록
  • 배열 리터럴의 요소 목록
  • 객체 리터럴의 프로퍼티 목록

35.1 함수 호출문의 인수 목록에서 사용하는 경우

요소들의 집합인 배열을 펼펴서 개별적인 값들의 목록으로 만든 후, 이를 함수의 인수 목록으로 전달해야 하는 경우가 있다.

  • Math.max 메서드는 매개변수 개수를 확정할 수 없는 가변 인자 함수. 다음과 같이 개수가 정해져 있지 않은 여러 개의 숫자를 인수로 전달 받아 인수 중에서 최대값을 반환.

  • 근데 숫자s가 아닌 배열을 인수로 전달하면 최대값 못 구함. 그래서 NaN을 반환.

  • 🙋 이 같은 문제를 해결하기 위해 배열을 펼쳐서 개별 값의 목록으로 만든 후 인수로 전달해야 한다. (1, 2, 3으로 펼쳐서)

  • 스프레드 문법이 제공되기 이전에는 배열을 펼쳐서 요소들의 목록을 함수의 인수로 전달하고 싶은 경우 Function.prototype.apply을 사용했다.

  • 스프레드 문법을 사용하면 더 간결하고 가독성이 좋다.

스프레드 문법은 앞에서 살펴본 Rest 파라미터와 형태가 동일하여 혼동할 수 있으므로 주의할 필요가 있다. Rest 파라미터는 함수에 전달된 인수들의 목록을 배열로 전달 받기 위해 매개변수 이름 앞에 ...을 붙이는 것. 스프레드 문법은 여러 개의 값이 하나로 뭉쳐 있는 배열과 같은 이터러블을 펼쳐서 개별적인 값들의 목록을 만드는 것. 따라서 Rest 파라미터와 스프레드 문법은 서로 반대의 개념


35.2 배열 리터럴 내부에서 사용하는 경우

35.2.1 concat

ES5 에서 2개의 배열을 1개의 배열로 결합하고 싶은 경우 배열 리터럴만으로 해결은 못하구 concat을 써야한다. 그러나 스프레드를 쓰면 다른 메서드를 쓰지 않아도 결합이 가능하다.

35.2.2 splice

ES5에서 어떤 배열의 중간에 다른 배열의 요소들을 추가하거나 제거하려면 splice 메서드를 사용. 이 때 splice 메서드의 세 번째 인수로 배열을 전달하면 배열 자체가 추가.

  • 위 예제의 경우 splice 메서드의 세 번째 인수 [3,4]을 3,4로 헤체해 전달해야 한다. 그렇지 않으면 arr1에 arr2 배열 자체가 추가된다. 따라서 이러한 경우 Function.prototype.apply 메서드를 사용하여 splice 메서드를 호출해야 한다. apply 메서드의 두 번째 인수(배열) apply 메서드가 호출하는 함수에 헤체되어 전달된다.

  • apply 메서드의 2번째 인수(배열)은 apply 메서드가 호출한 splice 메서드의 인수 목록이다.
  • apply 메서드의 2번째 인수 [1,0].concat(arr2)는 [1,0,3,4]으로 평가된다.
  • 따라서 splice 메서드에 apply 메서드의 2번째 인수 [1,0,3,4]이 헤체되어 전달된다.
  • 즉, arr3[1]부터 0개 요소를 제거하고 그 자리에 새로운 요소(3,4)를 삽입한다.
  • 스프레드 문법을 사용하면 다음과 같이 더욱 간결하고 가독성 좋게 표현할 수 있다


35.2.3 배열 복사

ES5에서 배열을 복사하려면 slice 메서드를 사용한다

스프레드 문법을 사용하면 다음과 같이 더욱 간결하고 가독성 좋게 표현할 수 있다.

이때 false 값을 보면 알 수 있듯 얕은 복사를 하여 새로운 복사본을 형성(스프레드, slice 모두)


35.2.4 이터러블을 배열로 변환

ES5에서 이터러블 배열로 변환하려면 Function.prototype.apply 또는 Function.prototype.call 메서드를 사용하여 slice 메서드를 호출해야 한다.

  • 스프레드 문법을 사용하면 좀 더 간편하게 이터러블을 배열로 변환 가능. arguments 객체는 이터러블이면서 유사 배열 객체. 따라서 스프레드 문법의 대상이 될 수 있다. 근데 더 좋은 방법은 Rest 파라미터를 이용하는 것이다.

  • 그러나 앞서 살펴본 것처럼 이터러블이 아닌 유사 배열 객체는 스프레드 문법이 될 수 없으며 ES6에서 도임된 Array.from 메서드를 사용해서 유사 배열 객체 또는 이터러블을 인수로 전달 받아 배열로 변환하여 반환

35.3 객체 리터럴 내부에서 사용하는 경우

Rest 프로퍼티와 함께 2021년 1월 현재 TS39 프로세스의 stage4(Finished) 단계에 제안되어 있는 스프레드 프로퍼티를 사용하면 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법을 사용할 수 있다. 스프레드 문법의 대상은 이터러블이어야 하지만 스프레드 프로퍼티 제안은 일반 객체를 대상으로도 스프레드 문법을 허용한다.

  • 스프레드 프로퍼티가 제안되기 이전에는 ES6에서 도입된 Object.assign 메서드를 사용해 여러개의 객체를 병합하거나 특정 프로퍼티를 변경 or 추가
  • 스프레드 프로퍼티는 Object.assign 메서드를 대체할 수 있는 간편한 문법이다


36장 디스트럭처링 할당

디스트럭처링 할당(destructuring assginment(구조 분해 할당)은 구조화된 배열과 같은 이터러블 또는 객체를 구조 파괴하여 1개 이상의 변수에 개별적으로 할당하는 것. 필요한 값만 추출하여 변수에 할당할 때 유용한다.

36.1 배열 디스트럭처링 할당

ES5 에서 구조화된 배열을 디스트럭처링하여 1개 이상 변수에 할당하는 방법

ES6의 배열 디스트럭처링 할당은 배열의 각 요소를 배열로부터 추출하여 1개 이상의 변수에 할당. 이때 배열 디스트럭처링 할당의 대상(할당문의 우변)은 이터러블이어야 하며, 할당 기준은 배열의 인덱스다. 즉, 순서대로 할당된다.

배열 디스트럭처링 할당을 위해서는 할당 연산자 왼쪽에 값을 할당받을 변수를 선언. 이때 변수를 배열 리터럴 형태로 선언하며 우변에 이터러블을 할당하지 않으면 에러가 발생.

배열 디스트럭처링 할당 변수의 선언문은 다음처럼 선언과 할당을 분리할 수도 있다. 단, 이 경우 const 키워드로 변수를 선언할 수 없으므로 권장하지 않는다.

배열 디스트럭처링 할당의 기준은 배열의 인덱스. 즉, 순서대로 할당된다. 이때 변수의 개수와 이터러블의 요소 개수가 반드시 일치할 필요가 없다.

  • 배열 디스트럭처링 할당을 위한 변수에 기본값 설정할 수 있다.

  • 기본값보다 할당된 값이 우선한다
  • 배열 디스트럭처링 할당은 배열과 같은 이터러블에서 필요한 요소만 추출하여 변수에 할당하고 싶을 때 유용. 다음 예제는 URL을 파싱하여 protocol, host, path 프로퍼티를 갖는 객체를 생성해 반환.

  • 배열 디스트럭처링 할당을 위한 변수에 Rest 파라미터와 유사하게 Rest요소 ... 을 사용할 수 있다. Rest 요소는 Rest 파라미터와 마찬가지로 반드시 마지막에 있어야 한다

36.2 객체 디스트럭처링 할당

ES5에서 객체의 각 프로퍼티를 객체로부터 디스트럭처링 해 변수에 할당하기 위해서는 프로퍼티 키를 사용해야 한다.

  • ES6 객체 디스트럭처링 할당은 객체의 각 프로퍼티를 객체로부터 추출하여 1개 이상의 변수에 할당. 이때 객체 디스트럭처링 할당의 대상은 객체여야 하며 할당 기준은 프로퍼티 키다. 즉, 순서는 의미가 없으며 선언된 변수 이름과 프로퍼티 키가 일치하면 할당된다

배열 디스트럭처링 할당과 마찬가지로 객체 디스트럭처링 할당을 위해서는 할당 연산자 왼쪽에서 프로퍼티 값을 할당받을 변수를 선언해야 한다. 이때 변수를 객체 리터럴 형태로 선언한다.

할당하지 않을 일도 업겠지만 만약 할당 안하면 에러난다. 그리고 리터럴로 선언한 변수이다. 이는 프로퍼티 축약 표현을 통해 선언한 것이다.

  • 객체 디스트럭처링 할당은 객체를 인수로 전달받는 함수의 매개변수에도 사용할 수 있다.

  • 위 예제에서 객체를 인수로 받는 매개변수 todo에 객체 디스트럭처링 할당을 사용하면 좀 더 가독성 좋게 표현할 수 있다.


배열의 요소가 객체인 경우 배열 디스트럭처링 할당과 객체 디스트럭처링 할당을 혼용할 수 있다.

  • 중첩 객체의 경우에는 다음과 같이 사용한다

  • address 프로퍼티 키로 객체를 추출하고 이 객체의 city 프로퍼티 키로 값을 추출한다
  • 객체 디스트럭처링 할당은 위한 변수에 Rest 파라미터나 Rest 요소와 유사하게 Rest 프로퍼티...을 사용할 수 있다. Rest 프로퍼티는 Rest 프로퍼티는 Rest 파라미터나 Rest 요소와 마찬가지로 반드시 마지막에 위치해야 한다.

0개의 댓글