• Gist


    Introduction

    Iterator is one of the most common design modes in daily development. Let's explore the iterator continent in the javacript world, here we go!

    Gist Iterator Mode

    It's the basic iterator mode concept:

    And it's like this in javascript world:

    Grammar rules

    Attention

    Assume that "iterable" is an adjective, and "iterableFn" is a iterable.
    It's a little confusing when lots of "iterable" appear at the same time.

    Relation between iterable and iterator

    Iterator can be created by iterableFn(an iterable), iterableFn belongs to iterable sources.

    Iterables

    Iterable sources

    • Array
    • String
    • Map
    • Set
    • Dom Elements
    • Arguments

    Get iterableFn(used to generate iterator)

    IterableFn can be derived from iterable source by its property: Symbol.iterator, for example: const iterableFn = [][Symbol.iterator]

    Symbol.iterator
    A method that returns the default Iterator for an object. Called by the semantics of the for-of statement.

    /** Test in chrome 55  **/
    // Array
    console.log( [][Symbol.iterator] )    // function values() { [native code] }
    
    // String
    console.log( ''[Symbol.iterator] )    // function [Symbol.iterator]() { [native code] }
    
    // Map
    console.log( new Map([[]])[Symbol.iterator] )    // function entries() { [native code] }
    
    // Set
    console.log( new Set([])[Symbol.iterator] )    // function values() { [native code] }
    
    // Dom elements
    console.log( document.getElementsByTagName('body')[Symbol.iterator] )    // function values() { [native code] }
    
    // arguments
    function test() {
    	console.log( arguments[Symbol.iterator] )
    }
    test(1, 2, 3)    // // function values() { [native code] }
    

    Iterable sources' consumers

    Follow consumers' implementations mainly depend on iterables.Howerver, the examples are irrelevant to topic.

    • for of
    for(const i in [1, 2]) {
        cosnole.log(i)
    }     
        // 1
        // 2
    
    • ...(The spread opeartor)
    console.log( [..."ab"] )     // ["a", "b"]
    
    • Array.from
    console.log( Array.from("ab") )    // ["a", "b"]
    

    Iterators

    Iterator is common used, as to decouple algorithms.

    Iterator = iterableFn()

    After iterable's implementation, it returns an object called iterator, which uses "next" method to iterate.

    /** Test in chrome 55  **/
    // Array
    console.log( [][Symbol.iterator]() )    // ArrayIterator {}
    
    // String
    console.log( ''[Symbol.iterator]() )    //  StringIterator {}
    
    // Map
    console.log( new Map([[]])[Symbol.iterator]() )    // MapIterator {[undefined, undefined]}
    
    // Set
    console.log( new Set([])[Symbol.iterator]() )    // SetIterator {}
    
    // Dom elements
    console.log( document.getElementsByTagName('body')[Symbol.iterator]() )    // ArrayIterator {}
    
    // arguments
    function test() {
    	console.log( arguments[Symbol.iterator]() )
    }
    test(1, 2, 3)    // ArrayIterator {}
    

    Add value and Implement method "next":

    /** Test in chrome 55  **/
    // Array
    console.log( [1, 2][Symbol.iterator]().next() )    // {value: 1, done: false}
    
    // String
    console.log( 'ab'[Symbol.iterator]().next() )    //  {value: 'a', done: false}
    
    // Map
    console.log( new Map([[1, 'a']])[Symbol.iterator]().next() )    // {value: [1, 'a'], done: false}
    
    // Set
    console.log( new Set([1, 1, 2])[Symbol.iterator]().next() )    // {value1: , done: false}
    
    // Dom elements
    console.log( document.getElementsByTagName('body')[Symbol.iterator]().next() )    // {value: body(dom), done: false}
    
    // arguments
    function test() {
    	console.log( arguments[Symbol.iterator]().next() )
    }
    test(1, 2, 3)    // {value: 1, done: false}
    

    Iterator = generator()

    Setting iterator mutually again and again seems inefficient, syntactic sugar is needed. Fortunately, ES6 provides the useful "generater"

    function* iteratorMaker() {
        yield 1
        yield 2
    }
    
    const iterator =  iteratorMaker()
    
    console.log( iterator )    // iteratorMaker {[[GeneratorStatus]]: "suspended", [[GeneratorReceiver]]: Window, [[GeneratorLocation]]: Object}
    
    console.log( iterator.next() )    // {value: 1, done: false}
    
    console.log( iterator.next() )    // {value: 2, done: false}
    
    console.log( iterator.next() )    // {value: undefined, done: true}
    

    Application

    Iterator can be applied in wide situations, there's a sample to generate increasing id numbers.

    function* idIteratorMaker() {
        let id = 0
        while (true) {
        	yield id++
        }
    }
    
    function create(idIterator) {
    	return idIterator.next().value
    }
    
    const idIterator = idIteratorMaker()
    
    const a = create(idIterator)
    const b = create(idIterator)
    const c = create(idIterator)
    
    console.log(a)     // 0
    console.log(b)     // 1
    console.log(c)     // 2
    

    Conclusion

    Obviously, iterator makes codes more readable and matainable.

    Reference

    1. http://exploringjs.com/es6/ch_iteration.html#sec_iterating-language-constructs
    2. https://tc39.github.io/ecma262/#table-1
  • 相关阅读:
    jdbc连接池工具与pg fdw连接的问题
    关于drill http存储插件http 超时的一些说明
    tds-fdw PostgreSQL said: DB-Library error: DB #: 20002, DB Msg: Adaptive Server connection failed, OS #: 0, OS Msg: Success, Level: 9 问题解决.md
    开发自己的jdbc驱动——可选开发工具
    nexus Invalid state: DELETED; allowed: [STARTED] 问题解决
    airline开发类似git cli 的jar 包
    开发自己的jdbc驱动——基本说明
    nessie 安装&&简单试用
    nessie 类似git 管理数据湖
    一些不错的开源大数据虚拟数据sql 查询引擎
  • 原文地址:https://www.cnblogs.com/terrysu/p/7091269.html
Copyright © 2020-2023  润新知