이터러블(iterable), 스프레드 문법, 디스트럭쳐링 할당

Kyung yup Lee·2021년 6월 29일
0

자바스크립트

목록 보기
11/12

이터러블이라 하면 흔히들 그냥 순회 가능한? 이라고 알고 있다. 나도 그랬다. 물론 이터러블의 목적은 순회를 하기 위해서 만들어졌다. 하지만 파고 들어가면 이 이터러블의 정의는 생각과는 약간 다르다.

정의

이터러블은 순회 가능한 자료구조를 만들기 위해 ECMAScript 사양에 정의한 규칙이다. 즉 프로토콜이라는 것. 이터러블은 이터러블 프로토콜을 준수한 객체를 의미한다.

ES6 이전에는 배열, 문자열, 유사 배열 객체, DOM 컬렉션 등이 규약 없이 각자 구조를 가지고 for문, for ... in 문, forEach 등으로 순회가 가능했다.

하지만 es6부터는 이런 제각각인 자료구조들을 하나의 프로토콜로 통합하여 사용할 필요성을 느꼈고, 순회 가능한 데이터 컬렉션은 이터러블 프로토콜을 반드시 지키도록 하여, 이 이터러블 프로토콜을 지킨 자료구조만 for ...of 문, 스프레드 문법, 배열 디스트럭쳐링 할당 문법을 사용할 수 있도록 했다.

이터러블 프로토콜

이터레이션 프로토콜에는 이터러블 프로토콜과 이터레이터 프로토콜이 있다. 하지만 개인적으로 이터레이션 프로토콜은 실존하는 개념이 아니며, 이터러블 프로토콜과 이터레이터 프로토콜을 통칭하기 위해 사용되는 용어라고 생각한다. 그래서 실질적으로 의미를 갖는 건 이터러블 프로토콜과 이터레이터 프로토콜이고, 특히 이터러블을 만들어주는 건 이터러블 프로토콜이기 때문에, 이 개념이 중요하다고 생각한다.

이터러블은 Symbol.iterator를 프로퍼티 키로 사용한 메서드를 오버라이딩 하거나, 상속받은 Symbol.iterator 메서드를 호출하면 이터레이터 프로토콜을 지키는 이터레이터를 반환한다.

이에 속하는 자료구조는 배열, 문자열, Map, Set이 있다.

이터레이터 프로토콜

이터레이터 프로토콜은 이터러블이 Symbol.iterator를 호출했을 때 반환되는 이터레이터의 규약이 된다.

이터레이터는 next 메서드를 가지고 있고, 이를 통해 이터러블을 순회하는 역할을 한다. 또한 value 와 done 을 갖는 이터레이터 리절트 객체를 반환하여 순회문을 끝낼 수 있다.

즉 이터레이터는 이터러블의 포인터 역할을 한다.

이터러블과 유사배열 객체

유사 배열 객체는 인덱스를 키로 갖고, length 프로퍼티를 가지고 있어, 마치 배열처럼 작동할 수 있는 객체를 뜻한다. 하지만 배열이 아니다.
배열의 조건은 Array.prototype을 상속받아야만 한다.

유사 배열 객체는 기본적으로 이터러블이 아닌 일반 객체이기 때문에 for or문으로 순회하거나 스프레드 문법, 배열 디스트럭쳐링 할당을 사용할 수 없다. 하지만 arguments, NodeList, HTMLCollection 자료구조는 유사 배열 객체이면서 이터러블이다. 유사배열객체이지만 Symbol.iterator 메서드를 구현해서, 이터러블 프로토콜을 준수한 것이다.

이처럼 이터러블 프로토콜을 준수할 수 있다면 유사배열객체도 이터러블로 동작할 수 있다.

스프레드 문법

이터러블을 설명했으니, 이터러블만 사용할 수 있는 스프레드 문법에 대해서도 알아야 한다. 스프레드 문법은 편하기 때문에 이를 사용하기 위해서라도 이터러블 프로토콜에 대해 알아야했다.
그럼 써야지.

사용법

스프레드 문법은 자료구조를 펼쳐 개별 값들의 목록으로 만드는 기능이다.

const arr = [1,2,3];
console.log(...arr); // 1 2 3

중요한 것은 스프레드 문법을 통해 나온 결과는 값이 아니다. 즉 변수에 할당할 수 없다.

사용처

함수 호출문의 인수 목록

Math.max([1,2,3]); 

위 코드의 결과는 NaN 이다. 문법에 맞지 않는 것이다.

Math.max 의 인수는 컴마로 구분된 숫자의 연속이다. 배열이나 객체가 아닌 것이다. 이럴 때 스프레드 문법이 유용하다.

Math.max(...[1,2,3]); // 3

배열 리터럴의 요소 목록

배열을 메서드 사용 없이 합치거나 추가 할 수 있다.
특히 스택 자료구조나, 큐 자료구조의 push 를 구현할 때 유용하게 사용할 수 있다.

const push = value => {
	let stack = [1,2,3]
	return [...stack, value]
}

이 방법을 응용해 배열이 아닌 이터러블을 배열로 쉽게 바꿀 수 있다.

[...유사배열객체]

이렇게 쓰면 배열로 바뀐다. Array.from 보다 간결하게 사용할 수 있다.

객체 리터럴의 프로퍼티 목록

원래 스프레드 문법은 이터러블만 사용할 수 있었지만, 스프레드 프로퍼티를 사용해 객체 리터럴의 프로퍼티 목록에서도 스프레드 문법이 사용가능하다.

디스트럭쳐링 할당

배열 디스트럭쳐링 할당

const arr = [1,2,3]
const [a,b,c] = arr;
// a = 1 b = 2 c = 3

객체 디스트럭쳐링 할당

객체에서도 마찬가지로 디스트럭쳐링 할당이 가능하다. 다만 배열에서는 인덱스를 기준으로 할당이 되었지만, 객체에서는 키를 기준으로 할당한다.

profile
성장하는 개발자

0개의 댓글