TypeScript Deep Dive
  • README
  • 시작하기
    • 왜 타입스크립트인가
  • 자바스크립트
    • 비교 연산자
    • 참조 연산자
    • Null vs. Undefined
    • this
    • 클로저
    • Number
    • Truthy
  • 미래의 자바스크립트
    • 클래스
      • 즉시실행함수
    • 화살표 함수
    • 나머지 연산자
    • let
    • const
    • 비구조화 할당
    • 전개 연산자
    • for...of
    • 이터레이터
    • 템플릿 리터럴
    • 프로미스
    • 제네레이터
    • Async Await
  • 프로젝트
    • 컴파일러 제어
      • tsconfig.json
      • 파일 경로 지정
    • 선언
    • 모듈화
      • 파일을 이용한 모듈화
      • globals.d.ts
    • 네임스페이스
    • 동적 표현식 가져오기
  • Node.js 시작하기
  • Browser 시작하기
  • 타입스크립트 타입 시스템
    • 자바스크립트 마이그레이션 가이드
    • @types
    • 주변 선언
      • 파일 선언
      • 변수
    • 인터페이스
    • 열거형(Enums)
    • lib.d.ts
    • 함수
    • 콜러블(Callable)
    • 타입 표명(Type Assertion)
    • 신선도(Freshness)
    • 타입 가드
    • 리터럴(Literal)
    • 읽기 전용(readonly)
    • 제네릭
    • 타입 인터페이스
    • 타입 호환성
    • Never 타입
    • 구별된 유니온
    • 인덱스 서명(Index Signature)
    • 타입 이동하기
    • 예외 처리
    • 믹스인(Mixin)
  • JSX
    • React
    • Non React JSX
  • Options
    • noImplicitAny
    • strictNullChecks
  • 타입스크립트 에러
    • 에러 메세지
    • 공통 에러
  • NPM
  • 테스트
    • Jest
    • Cypress
  • Tools
    • Prettier
    • Husky
    • ESLint
    • Changelog
  • 팁
    • 문자열 Enums
    • 타입 단언
    • 상태 저장 함수
    • 커링
    • 제네릭 타입 예시
    • 객체 타입 설정
    • 유용한 클래스
    • Import / Export
    • 속성 Setters
    • outFile 주의사항
    • 제이쿼리 팁
    • 정적 생성자
    • 싱글톤 패턴
    • 함수 파라미터
    • 토글 생성
    • Import 여러개 하기
    • 배열 생성
    • 생성자에서 타입정의
  • 스타일 가이드
  • 타입스크립트 컴파일러 구조
    • Program
    • AST
      • TIP: Visit Children
      • TIP: SyntaxKind enum
      • Trivia
    • Scanner
    • Parser
      • Parser Functions
    • Binder
      • Binder Functions
      • Binder Declarations
      • Binder Container
      • Binder SymbolTable
      • Binder Error Reporting
    • Checker
      • Checker Diagnostics
      • Checker Error Reporting
    • Emitter
      • Emitter Functions
      • Emitter SourceMaps
    • Contributing
Powered by GitBook
On this page

Was this helpful?

  1. 미래의 자바스크립트

이터레이터

이터레이터 자체는 타입스크립트 혹은 ES6 기능이 아닙니다. 이터레이터는 객체 지향 프로그래밍 언어에서 동작합니다. 그것은 일반적으로 다음 인터페이스를 구현하는 객체입니다.

interface Iterator<T> {
    next(value?: any): IteratorResult<T>
    return?(value?: any): IteratorResult<T>
    throw?(e?: any): IteratorResult<T>
}

(More on that <T> notation later) 이 인터페이스를 사용하면 일부 콜렉션 또는 시퀀스에서 값을 검색할 수 있습니다.

그 IteratorResult는 단순히 value+done 쌍입니다.

interface IteratorResult<T> {
    done: boolean
    value: T
}

어떤 프레임의 객체가 있다고 상상해 보십시요, 이 프레임이 구성하는 요소 이터레이터를 사용하면 가능합니다. 아래처럼 프레임 객체에서 컴포넌트를 검색합니다.

class Component {
    constructor(public name: string) {}
}

class Frame implements Iterator<Component> {
    private pointer = 0

    constructor(public name: string, public components: Component[]) {}

    public next(): IteratorResult<Component> {
        if (this.pointer < this.components.length) {
            return {
                done: false,
                value: this.components[this.pointer++]
            }
        } else {
            return {
                done: true,
                value: null
            }
        }
    }
}

let frame = new Frame('Door', [
    new Component('top'),
    new Component('bottom'),
    new Component('left'),
    new Component('right')
])
let iteratorResult1 = frame.next() //{ done: false, value: Component { name: 'top' } }
let iteratorResult2 = frame.next() //{ done: false, value: Component { name: 'bottom' } }
let iteratorResult3 = frame.next() //{ done: false, value: Component { name: 'left' } }
let iteratorResult4 = frame.next() //{ done: false, value: Component { name: 'right' } }
let iteratorResult5 = frame.next() //{ done: true, value: null }

//It is possible to access the value of iterator result via the value property:
let component = iteratorResult1.value //Component { name: 'top' }

다시 말하자면 이터레이터 자체는 타입스크립트 기능이 아닙니다. 이 코드는 이터레이터 및 IteratorResult를 명시적으로 구현합니다. 그리고 이러한 공통점을 사용하는 것은 매우 유용합니다. ES6 interfaces for code consistency.

그래 좋아, 그러나 많은 도움이 되었어. ES6는 이터러블 프로토콜을 정의합니다 이터러블 인터페이스가 구현 된 경우 [Symbol.iterator] symbol을 포함합니다.

//...
class Frame implements Iterable<Component> {
    constructor(public name: string, public components: Component[]) {}

    [Symbol.iterator]() {
        let pointer = 0
        let components = this.components

        return {
            next(): IteratorResult<Component> {
                if (pointer < components.length) {
                    return {
                        done: false,
                        value: components[pointer++]
                    }
                } else {
                    return {
                        done: true,
                        value: null
                    }
                }
            }
        }
    }
}

let frame = new Frame('Door', [
    new Component('top'),
    new Component('bottom'),
    new Component('left'),
    new Component('right')
])
for (let cmp of frame) {
    console.log(cmp)
}

유감스럽게도 frame.next()는 이 패턴과 함께 작동하지 않을 것으로 보입니다.

//...
class Frame implements IterableIterator<Component> {
    private pointer = 0

    constructor(public name: string, public components: Component[]) {}

    public next(): IteratorResult<Component> {
        if (this.pointer < this.components.length) {
            return {
                done: false,
                value: this.components[this.pointer++]
            }
        } else {
            return {
                done: true,
                value: null
            }
        }
    }

    [Symbol.iterator](): IterableIterator<Component> {
        return this
    }
}
//...

frame.next() 그리고 for 둘다 이터러블이터레이터 인터페이스로 잘 동작합니다.

이터레이터는 이터레이트 값을 가지고 있지 않습니다. 이 예제는 전형적인 피보나치입니다.

class Fib implements IterableIterator<number> {
    protected fn1 = 0
    protected fn2 = 1

    constructor(protected maxValue?: number) {}

    public next(): IteratorResult<number> {
        var current = this.fn1
        this.fn1 = this.fn2
        this.fn2 = current + this.fn1
        if (this.maxValue != null && current >= this.maxValue) {
            return {
                done: true,
                value: null
            }
        }
        return {
            done: false,
            value: current
        }
    }

    [Symbol.iterator](): IterableIterator<number> {
        return this
    }
}

let fib = new Fib()

fib.next() //{ done: false, value: 0 }
fib.next() //{ done: false, value: 1 }
fib.next() //{ done: false, value: 1 }
fib.next() //{ done: false, value: 2 }
fib.next() //{ done: false, value: 3 }
fib.next() //{ done: false, value: 5 }

let fibMax50 = new Fib(50)
console.log(Array.from(fibMax50)) // [ 0, 1, 1, 2, 3, 5, 8, 13, 21, 34 ]

let fibMax21 = new Fib(21)
for (let num of fibMax21) {
    console.log(num) //Prints fibonacci sequence 0 to 21
}

Building code with iterators for ES5 target

위의 코드 예제에는 ES6가 필요합니다. 그러나 JS엔진이 Symbol.iterator을 지원한다면 ES5에서도 사용할 수 있습니다. 타겟을 ES5으로 설정하고, ES6 lib를 사용하여 컴파일하면 됩니다 (프로젝트에 es6.d.ts 추가) 컴파일된 코드는 node 4+, Google Chrome 등의 브라우저에서 작동 가능합니다.

Previousfor...ofNext템플릿 리터럴

Last updated 4 years ago

Was this helpful?