• ES6新增----深入理解generator


    参考学习:https://www.cnblogs.com/wangfupeng1988/p/6532713.html
    https://www.cnblogs.com/diligenceday/p/5488037.html
    http://www.ruanyifeng.com/blog/2015/04/generator.html
    https://blog.csdn.net/hj7jay/article/details/53905868
    先来一段最基础的Generator代码

    function* Hello() {
        yield 100
        yield (function () {return 200})()
        return 300
    }
    
    var h = Hello()
    console.log(typeof h)  // object
    
    console.log(h.next())  // { value: 100, done: false }
    console.log(h.next())  // { value: 200, done: false }
    console.log(h.next())  // { value: 300, done: true }
    console.log(h.next())  // { value: undefined, done: true }
    

    Iterator遍历器
    1.Symbol是一个特殊的数据类型,和number string等并列

    // 数组
    console.log([1, 2, 3][Symbol.iterator])  // function values() { [native code] }
    // 某些类似数组的对象,NoeList
    console.log(document.getElementsByTagName('div')[Symbol.iterator])  // function values() { [native code] }
    

    2.在 ES6 中,原生具有[Symbol.iterator]属性数据类型有:数组、某些类似数组的对象(如arguments、NodeList)、Set和Map。其中,Set和Map也是 ES6 中新增的数据类型。

    var item
    for (item of [100, 200, 300]) {
        console.log(item)
    }
    // 打印出:100 200 300 
    // 注意,这里每次获取的 item 是数组的 value,而不是 index ,这一点和 传统 for 循环以及 for...in 完全不一样
    

    3.生成Iterator对象
    定义一个数组,然后生成数组的Iterator对象

    const arr = [100, 200, 300]
    const iterator = arr[Symbol.iterator]()  // 通过执行 [Symbol.iterator] 的属性值(函数)来返回一个 iterator 对象
    

    4.iterator,那么该如何使用它呢 ———— 有两种方式:next和for…of。
    先说第一种,next

    console.log(iterator.next())  // { value: 100, done: false }
    console.log(iterator.next())  // { value: 200, done: false }
    console.log(iterator.next())  // { value: 300, done: false }
    console.log(iterator.next())  // { value: undefined, done: true }
    

    再说第二种,for…of

    let i
    for (i of iterator) {
        console.log(i)
    }
    // 打印:100 200 300 
    

    Generator
    1.Generator,就是生成一个Iterator对象。因此才会有next(),也可以通过for…of来遍历。

    function* Hello() {
        yield 100
        yield (function () {return 200})()
        return 300 
    }
    const h = Hello()
    console.log(h[Symbol.iterator])  // [Function: [Symbol.iterator]]
    

    2.const h = Hello()得到的就是一个iterator对象,因为h[Symbol.iterator]是有值的。既然是iterator对象,那么就可以使用next()和for…of进行操作

    console.log(h.next())  // { value: 100, done: false }
    console.log(h.next())  // { value: 200, done: false }
    console.log(h.next())  // { value: 300, done: false }
    console.log(h.next())  // { value: undefined, done: true }
    
    let i
    for (i of h) {
        console.log(i)
    }
    

    Generator 的具体应用
    next和yield参数传递
    1.yield后面的数据被返回,存放到返回结果中的value属性中。

    function* G() {
        yield 100
    }
    const g = G()
    console.log( g.next() ) // {value: 100, done: false}
    

    2.还有另外一个方向的参数传递,就是next向yield传递。

    function* G() {
        const a = yield 100
        console.log('a', a)  // a aaa
        const b = yield 200
        console.log('b', b)  // b bbb
        const c = yield 300
        console.log('c', c)  // c ccc
    }
    const g = G()
    g.next()    // value: 100, done: false
    g.next('aaa') // value: 200, done: false
    g.next('bbb') // value: 300, done: false
    g.next('ccc') // value: undefined, done: true
    

    3.for…of的应用示例,用简单几行代码实现斐波那契数列。

    function* fibonacci() {
        let [prev, curr] = [0, 1]
        for (;;) {
            [prev, curr] = [curr, prev + curr]
            // 将中间值通过 yield 返回,并且保留函数执行的状态,因此可以非常简单的实现 fibonacci
            yield curr
        }
    }
    for (let n of fibonacci()) {
        if (n > 1000) {
            break
        }
        console.log(n)
    }
    

    4.yield*语句,如果有两个Generator,想要在第一个中包含第二个,如下需求:

    function* G1() {
        yield 'a'
        yield 'b'
    }
    function* G2() {
        yield 'x'
        yield 'y'
    }
    
    function* G1() {
        yield 'a'
        yield* G2()  // 使用 yield* 执行 G2()
        yield 'b'
    }
    function* G2() {
        yield 'x'
        yield 'y'
    }
    for (let item of G1()) {
        console.log(item)
    }
    

    5.Generator 不是函数,更不是构造函数,构造函数返回的是this,而Generator返回的是一个Iterator对象。完全是两码事,

  • 相关阅读:
    chrome调试Android webview页面
    Ractive 的 一些认识
    backbone的一些认识
    关于Maven打包(Jar)时文件过滤的正确做法
    网页中实现微信登录(OAuth)的不完整记录
    将项目发布到Maven中央仓库时关于GPG的一些操作日志
    记录一下自己在 eclipse 中使用的 javadoc 模板
    记录一下MySQL的表分区常用操作
    在H5 App中实现自定义Token的注意事项
    再来复习一下Javascript中关于数组和对象的常用方法
  • 原文地址:https://www.cnblogs.com/princeness/p/11664964.html
Copyright © 2020-2023  润新知