본문 바로가기
NodeJS/FuncP

Iterator, Iterable

by MiteDev 2024. 2. 19.

Iterator/Iterable Protocol

Iterator: { value, done} 객체를 return 하는 next()를 가진 객체 

Iterable: Iterator를 return하는 [Symbol.iterator]()를 가진 객체

  // 배열이나  string, Map, Set 등이 Iterable 객체에 해당한다.

Iterator/Iterable Protocol: [for...of], [Spread Operator] 등 이터러블이나 이터레이터 프로토콜을 따르는 연산자함게 동작하도록 하는 규약

 

// Iterable
const u_iterable = {
	[Symbol.iterator]() {
    	let i = 3;
        return {
            next() {
            	return i === 0 ? { value: undefined, done: true} : {value: i--, done: false}
            }
        }
    }
}

// Iterator
const u_iterator = u_iterable[Symbol.iterator]();

for(const it of u_iterable) console.log(it) // 3, 2, 1
for(const it of u_iterator) console.log(it) // Uncaught TypeError: u_iterator is not iterable

 

  u_iterator 변수에 u_iterable[Symbol.iterator]()를 할당했는데 왜 u_iterator 변수가 iterable이 아니라는 에러가 뜰까?

Iterable의 정의를 다시 한번 보면 Iterator를 return하는 [Symbol.iterator]()를 가진 객체가 Iterable이라고 쓰여있다 하지만 콘솔을 찍어보면 아래와 같이 u_iterator에는 next() 만 존재하기 때문에 iterable이 아니라는 에러가 뜨는것이다.

 

그럼 u_iterator를 iterable로 만드는 방법은 간단하게 [Symbol.iterator]()를 사용했을 때 자기 자신을 return 해주기만 하면 된다. 이를 well-formed iterator라고 하며, iterator 객체는 iterable 해야하고 자기 자신을 return해야 한다. 즉 u_iterator[Symbol.iterator]() === u_iterator 해야 한다. 

// Iterable
const u_iterable = {
	[Symbol.iterator]() {
    	let i = 3;
        return {
            next() {
            	return i === 0 ? { value: undefined, done: true} : {value: i--, done: false}
            },
            [Symbol.iterator]() { return this; }
        }
    }
}

// Iterator
const u_iterator = u_iterable[Symbol.iterator]();

for(const it of u_iterable) console.log(it); // 3, 2, 1
for(const it of u_iterator) console.log(it); // 3, 2, 1
console.log(u_iterator[Symbol.iterator]() === u_iterator); // true

'NodeJS > FuncP' 카테고리의 다른 글

Go, Pipe, Curry  (1) 2024.02.20
함수형 프로그래밍이란?  (2) 2024.02.19