Javascript

이터러블과 이터레이터(Iterable, Iterator protocol)

jennyiscoding 2022. 10. 6. 15:41

이터레이션

for-of loop나 spread 연산자를 쓸 수 있는 것을 이터레이션이라고 한다. 

해당하는 것은 Array, String, Map, Set, NodeList에 해당한다. 

이것들 안에 [Symbol.iterator]가 들어가 있어서 for-of loop나 spread 연산자를 쓸 수 있다. 

 

 

 

 

 

 

1. 이터러블 

이터러블 프로토콜 : 이터러블 프로토콜을 준수한 객체를 이터러블이라고 한다. for .. of문으로 순회할 수 있으며 스프레드 문법과 배열 디스트럭처링 할당의 대상으로 사용할 수 있다. 

이터레이터 프로토콜 : 이터레이터 프로토콜은 준수한 객체를 이터레이터라고 한다. 

const isIterable = v => v !== null && typeof v[Symbol.iterator] === 'function';

console.log(isIterable([])); // true
console.log(typeof [][Symbol.iterator]) //function이 나옴!

 

이터러블인지 확인하는 함수 구현1

const array = [1,2,3];
console.log(Symbol.iterator in array); //true

const object = {a: 1, b:2}
console.log(Symbol.iterator in object) //false

==> 아! Symbol.iterator가 안에 있어서 사용 가능하구나! 

 

이터러블인지 확인하는 함수 구현2

const isIterable = v => v !== null && typeof v[Symbol.iterator] === 'function';

console.log(isIterable([])); // true
console.log(isIterable('heell')) // true
console.log(isIterable(new Map())) // true
console.log(isIterable(new Set())) // true
console.log(isIterable({})) // false

==> 배열은 Array.prototype의 Symbol.iterator메서드를 상속받는 이터러블이다. 

 

const array = [1,2,3];

for (const item of array){
	console.log(item)
}

 

이터러블인 경우 ...스프레드 연산자를 쓸 수 있다. 

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

 

이터러블인 배열은 배열 디스트럭처링 할당의 대상으로 사용할 수 있다. 

const array = [1,2,3,4,5]
const [a, ...rest] = array;
console.log(a, ...rest) // 1 2 3 4 5
console.log(...array) // 1 2 3 4 5
console.log(rest) // [2,3,4,5]

 

객체는 이터러블이 아니지만 아래 형태로는 스프레드 연산자를 사용할 수 있다. 

객체 복제 시. 

let obj = {a: 1, b:2}
let abc = {}
abc = {...obj}

abc.cdf = {c: 3}

console.log(obj) // { a: 1, b: 2 }
console.log(abc) // { a: 1, b: 2, cdf: { c: 3 }}

 

2. 이터레이터

어터러블의 Symbol.iterator메서드를 호출하면 이터레이터 프로토콜을 준수한 이터레이터를 반환한다. 이터러블의 Symbol.iterator 메서드가 반환한 이터레이터는 next메서드를 갖는다. 

const array = [1,2,3];
const iterator = array.values();

console.log(iterator.next());//{ value: 1, done: false }
console.log(iterator.next());//{ value: 2, done: false }
console.log(iterator.next());//{ value: 3, done: false }
console.log(iterator.next());//{ value: undefined, done: true }