iterable
객체란?
배열을 일반화 한 객체이다.
이터러블이라는 개념을 사용하면 어떤 객체든 for..of
반복문을 사용할 수 있다.
배열은 이터러블객체중 대표적이다.
또한 문자열도 이터러블이다.
배열이 아닌 객체중에 컬렉션을 나타내는 객체일 경우,
for..of
문버을 적용할 수만 있다면 컬렉션을 순회하는데 유용할 것이다.
객체에 Symbol.iterator(특수 내장 심볼)이라는 메서드를 추가해 아래와 같은 일이 발생하게 한다.
for..of
가 시작되자마자 Symbol.iterator
를 호출한다.Symbol.iterator
는 반드시 이터레이터를 반환해야 함for..of
는 반환된 객체만을 대상으로 동작for..of
에 다음 값이 필요하면, for..of
는 이터레이터의 next()
메서드를 호출한다.next()
의 반환값은 {done: Boolean, value: any}와 같은 객체의 형태여야 한다. done=true
는 반복이 종료 되었음을 의미, done=false
일땐 value에 다음값이 저장된다.아래의 예제를 한번 보자.
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) { console.log(num); // 1, then 2, 3, 4, 5 }
이터러블 객체는 관심사의 분리
에 있다.
let rage = { from: 1, to: 5, [Symbol.iterator]() { this.current = this.from; return this; }, next() { if(this.current <= this.to) { return { done: false, value: this.current++ }; }else { return { done: true }; } }; for (let num of range) { console.log(num); // 1, then 2, 3, 4, 5 }
많은 이터레이터
무수히 많은 이터레이터도 가능하다.
range에서 range.to에 Infinity를 할당한다면 range가 무한대가 된다.
많은 난수를 생성하는 이터러블 객체를 만드는게 가능하다.
next에는 제약사항이 없다. next가 값을 계속 반환하는 것은 정상적인 작동이다. 그리고 beak를 활용하면 반복을 멈출 수 있다.
배열과 문자열은 가장 광법위하게 쓰이는 내장 이터러블이다.
for(let char of "hello") {
console.log(char); // 'h', 'e', 'l', 'l', 'o'
}
for..of
를 사용했을 때와 동일한 방법으로 문자열을 순회 할 때, 직접 호출을 통해 순회를 해보자.
let str = "Code";
let iterater = str[Symbol.iterator]();
while (true) {
let result = iterator.next();
if(result.done) { break; }
console.log(result.value);
}
이렇게 명시적으로 호출하는 경우는 드문데 이 방법을 사용하면 반복과정을 좀더 잘 통제할 수 있다.
반복을 시작했다가 잠시 멈춰 다른작업을 하다가 다시 반복을 시작하는 것과 같이 여러개로 쪼개는 것이 가능하다.
이터러블과 비슷해보지이만 많이 다른 용어이다.
Symbol.iterator
가 구현된 객체자바스크립트를 사용해 문제를 해결할 때 이터러블 객체나 유사 배열 객체 또는 둘다인 객체를 만날 수 있다.
이 두가지를 다 가지고 있는것중 대표적인게 문자열
이다.
하지만, 이터러블 객체라고 해서 유사배열인것은 아니다.
그리고 유사배열이라고 해서 이터러블 객체가 아니다
이터러블과 유사배열은 대개 배열이 아니기 때문에 push
, pop
등의 배열 메서드를 지원하지 않는다.
범용 메서드 Array.from은 이터러블이나 유사배열을 인자로 받아 진짜 배열
로 만들어준다.
let arrayLike = {
0: 'Hello',
1: 'world',
length: 2,
};
let arr = Array.from(arrayLike);
console.log(arr.pop()); // 'world'