이터러블 객체

여전히 이터러블 / 이터레이터 개념이 무엇인지 모를것입니다. 직접 이터러블 객체를 만들어 이터러블이라는 개념을 이해해 보도록 합시다.

let range = { // 1) 객체 생성
	from: 1,
	to: 5,
};

range[Symbol.iterator] = function() { // 2) 새로운 key:value 를 추가한다. key는 변수형태, value는 함수이다.
	return { // 객체를 리턴한다. 그런데 좀 특별한 형태의 객체
		current: this.from,
		last: this.to,

		next() { // 3) next() 정의
			if(this.current <= this.last) {
				return { value: this.current++, done: false };
				// 4) { value: 값, done: true/false } 형태의 이터레이터 객체를 리턴합니다.
			} else {
				return { done: true };
			}
		}
	}
}

평범한 range 객체를 이터러블 객체로 만드는 과정을 봅시다.

  1. 평범한 range 객체를 만든다.
  2. 우리가 흔히쓰는 객체에 새로운 key: value 를 추가하고 싶을 때, range[key] = value 를 통해 Symbol.iterator key값, value는 익명 함수를 통해 지정해 주었다.
  3. 추가한 함수는 어떠한 특별한 객체를 return 하게 되어있고, 이 객체 안에 next() 라는 메소드를 정의 하였다.
  4. 최종적으로 { value: 값, done: true/false } 형태의 이터레이터 객체를 return 한다.

그럼 이제 무엇이 이터러블 객체이고, 무엇이 이터레이터 일까?

Untitled

이터러블 객체가 for..of 에서 어떻게 순회하는지 과정

let range = { *// 객체 생성*
	from: 1,
	to: 5,
};

*// 1) for..of 최초 호출 시, Symbol.iterator가 호출됩니다.*
range[Symbol.iterator] = function() {

	*// Symbol.iterator는 이터레이터 객체를 반환합니다.
	// 2) 이후 for..of는 반환된 이터레이터 객체만을 대상으로 동작하는데, 이때 다음 값도 정해집니다.*
	return {
		current: this.from,
		last: this.to,

		*// 3) for..of 반복문에 의해 반복마다 next()가 호출됩니다.*
		next() {
			*// 4) next()는 값을 객체 { done: .., value: .. } 형태로 반환해야 합니다.*
			if(this.current <= this.last) {
				return { done: false, value: this.current++ }; *// 반복 순회 진행*
			} else {
				return { done: true }; *// 반복 순회 종료*
			}
		}
	};
};

for(let num of range) {
	alert(num); *// 1, 2, 3, 4, 5*
}
  1. for..of 가 시작되자마자 for..of는 Symbol.iterator 를 호출합니다.