06-1. 반복기와 생성기

euNung·2022년 6월 7일
0

타입스크립트

목록 보기
5/10
  • 반복기

    대부분의 프로그래밍 언어에서 반복기는 다음과 같은 특징이 있는 객체

    1. next라는 이름의 메서드를 제공한다
    2. next 메서드는 value와 done이라는 두 개의 속성을 가진 객체를 반환한다
const createRangeIterable = (from: number, to: number) => {
    let currentValue = from
    return {
        next() {
            const value = currentValue < to ? currentValue++ : undefined
            const done = value === undefined
            return { value, done }
        }
    }
}

const iterator1 = createRangeIterable(1, 3 + 1)
while(true) {
    const { value, done } = iterator1.next()
    if(done) break
    console.log(value)
}

const range = (from: number, to: number): number[] => from < to ? [from, ...range(from+1, to)] : []

for (const value of range(1, 3 + 1)) {
    console.log('range ', value)
}

// 에러 발생 => [Symbol.iterator] 메서드가 없음
const iterable = createRangeIterable(1, 3 + 1)
for (const value of iterable) {
    console.log(value)
 }

class RangeIterable {
    constructor(public from: number, public to: number) {}
    [Symbol.iterator]() {
        const self = this
        let currentValue = self.from
        return {
            // 메서드로써 동작하므로 this 는 인스턴스를 가리키게 된다.
            // 따라서 to가 RangeIterable 를 가리키도록 self 에다가 this 를 담는다
            next() {
                const value = currentValue < self.to ? currentValue++ : undefined
                const done = value === undefined
                return {value, done}
            }
        }
    }
}

const iterator2 = new RangeIterable(1, 3 + 1)
for (const value of iterator2) {
    console.log('RangeIterable ', value)
}
  • Iterable< T > & Iterator< T >
    • Iterable< T >
      : 반복기 제공자
      : 자신을 구현하는 클래스가 [Symbol.iterator] 메서드를 제공한다는 것을 명확하게 알려줌
    • Iterator< T >
      : 반복기
      : 반복기가 생성할 값의 타입을 명확하게 알려줌
class 구현 클래스 implements Iterable<생성할 값의 타입> {}

[Symbol.iterator](): Iterator<생성할 값의 타입> {}

ex)

class StringIterable implements Iterable<string> {
    constructor(private strings: string[] = [], private currentIndex: number = 0) {
    }
    [Symbol.iterator](): Iterator<string> {
        const self = this;
        let currentIndex = self.currentIndex, length = self.strings.length
        
        const iterator: Iterator<string> = {
            next(): {value: string, done: boolean} {
                const value = currentIndex < length ? self.strings[currentIndex++] : undefined
                const done = value === undefined
                return { value, done }
            }
        }
        return  iterator
    }
}

for (const value of new StringIterable(['hello', 'world', '!'])) {
    console.log(value)
}

  • [Symbol.iterator] 사용하기 위해 lib에 ES2015 &
    downlevelIteration 추가
// tsconfig.json
{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "lib": ["dom", "dom.iterable", "ES2015"],
    "esModuleInterop": true,
    "moduleResolution": "node",
    "sourceMap": true,
    "downlevelIteration": true,
  },
  "exclude": [
    "node_modules"
  ]
}

✅ for...of 구문은 next() 메서드 자동 호출

profile
프론트엔드 개발자

0개의 댓글