TIL #1 - 자바스크립트 이터러블/이터레이터 프로토콜
목표❗
📌 이터러블/이터레이터 프로토콜에 대해 설명할 수 있다.
📌 for...of 문의 순회 과정을 설명할 수 있다.
ES6 이전에는
위와 같이 인덱스로 접근하여 배열을 순회하였었다.
하지만 ES6부터는
이렇게 for...of 문을 통하여서 순회가 가능해졌다.
이게 어떻게 가능해지게 된 것일까?
이것을 알기위해선 이터러블/이터레이터 프로토콜에 대한 이해가 필요하다.
이터러블이란❓
- 이터러블 프로토콜을 준수한 객체
- Symbol.iterator 가 구현된 객체
- for...of 을 사용할 수 있는 객체
- 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용 가능한 객체
위와 같이 설명할 수 있다.
즉, Symbol.iterator 가 구현되어 있다면 순회가 가능하다.
반대로 말하면, Symbol.iterator가 구현되어 있지 않다면? 순회가 불가능하다.
한 번 확인해보자.
<출력값>
첫번째 출력값은 문제없이 잘 출력된다. 배열 역시 이터러블 객체이기 때문에 for...of 문으로 순회가 가능하다.
하지만, Symbol.iterator 을 없애주고 다시 for...of 문으로 순회하면 타입에러가 발생한다.
이는 선언한 배열 arr이 더이상 이터러블이 아니라고 인식하기 때문이다.
즉, Symbol.iterator를 가지고 있는 객체만이 이터러블이라고 말할 수 있다.
여기서 잠깐! for...in과 for...of의 차이를 알아보자.
for...in
- 객체의 프로퍼티 어트리뷰트 [[Enumerable]]의 값이 true인 프로퍼티들을 순회하면서 열거한다.
- 모든 객체에서 사용 가능하다.
for...of
- 이터레이터 next메소드를 호출하여 이터러블을 순회한다.
- 이때 next메소드는 value와 done값을 반환한다.
- 또한, next 메소드는 이터레이터 result 객체의 value 프로퍼티 값을 for of 문에 선언한 변수에 할당하게 된다.
for...of 문은 next 메소드가 있어야 사용가능하다. 즉, [Symbol.iterator] 속성을 가져야만 사용 가능하다는 소리.
대표적으로 Array, Set, Map, arguments가 있다.
이터레이터? 이터레이터는 또 뭘까?
이터레이터란 ❓
- value와 done을 반환하는 next 메소드를 가지고 있으며, 이를 이용해서 객체의 이터레이터 프로토콜을 구현하는 객체
- 이때 value 값에는 현재 값이 저장되고, done 에는 순회가 종료되었는지를 나타내는 boolean 값이 저장된다.
- 이는 [Symbol.iterator]() 안에 정의되어 있다.
<출력 값>
이 next메소드가 반환하는 값을 통해서 for...of 문이 순회를 할 수 있게 되는 것이다.
정리해보자면
- 이터러블은 Symbol.iterator 를 가지고 있고 순회할 수 있는 객체
- 이터레이터는 next 메소드를 호출하면 value와 done을 반환하는 객체
보통 이터러블을 말할 때 유사배열도 같이 비교하곤 한다.
이 둘의 차이점도 함께 알아보자.
유사배열
- index와 length 프로퍼티가 있는 객체
이터러블
- Symbol.iterator가 구현된 객체
이터러블 객체이면 유사 배열 객체인가? NO.
유사 배열 객체이면 이터러블 객체인가? NO.
대표적으로 유사배열이면서 이터러블인 것들이 있다.
- arguments
- NodeList
- HTMLCollection
위 3가지는 유사배열이면서 이터러블이다.
이터러블/이터레이터 프로토콜 이란❓
이터러블과 이터레이터는 각 프로토콜을 따른다.
이터러블 프로토콜
- 이터러블을 for...of 문이나 전개 연산자 등과 함께 동작하도록 한 규칙이다.
- 이터러블은 이터러블 프로토콜을 따른다. 즉, 이터러블은 for...of문이나 전개 연산자에 동작하는 객체이다.
이터레이터 프로토콜
- value들의 sequence를 만드는 표준 방법을 정의
- 객체가 next() 메소드호출 하면 이터러블을 순회해야 하고 value, done 프로퍼티를 갖는 이터레이터 리절트 객체를 반환한다.
👨💻 마무리
함수형 프로그래밍을 공부하면서 이터러블, 이터레이터에 대한 학습이 더 필요하다고 느꼈다.
이번 포스팅을 통해 for...in 문과 for...of 문의 차이점을 알고 어떻게 ES6에서 사용되는 메소드들이 순회를 하는지를 알게 되었다.
나는 파이썬을 초반에 배워서 오히려 ES5에서 사용하던 인덱스로 접근하는 방식이 익숙했었다.
이후 자바스크립트를 통해 문제들을 풀어가면서도 그 습관이 남아있었는데, 나중에는 의식해서 고차함수들을 써보는 연습들을 해보면서 적용시켜보았다.
하지만, 고차함수들을 쓰는 방법만 익히고 어떠한 원리로 이 동작들이 이루어지는 지에 대해서는 정확히 모르고 있었던 것 같다.
함수형 프로그래밍 공부를 통해 이터러블/이터레이터 프로토콜에 대한 중요성을 느꼈고, 그동안 내가 써오던 고차함수에 대해 더 깊게 공부하게된 계기가 되었다.
앞으로 더 공부를 해보면서 고차함수를 사용하는 원리에 대해 더 이해해보고 함수형 프로그래밍에 필요한 기초 지식들을 잘 닦아볼 것이다.
📚 참고
모던 자바스크립트 Deep Dive
https://developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Iteration_protocols
'성장기록 > TIL' 카테고리의 다른 글
TIL #6 - SSR과 CSR (1) | 2023.01.09 |
---|---|
TIL #5 - fork 한 레포지토리 잔디 심기 (0) | 2023.01.08 |
TIL #4 - CSS-in-JS 란? (0) | 2023.01.07 |
TIL #3 - 함수형 프로그래밍이란? (0) | 2023.01.05 |
TIL #2 - React Life Cycle (생명 주기) (0) | 2023.01.04 |