黑马程序员技术交流社区

标题: 【成都校区】--- ES6中的迭代器和生成器 [打印本页]

作者: 小刀葛小伦    时间: 2019-12-19 14:28
标题: 【成都校区】--- ES6中的迭代器和生成器
迭代?
顾名思义,更新迭代。在JS中迭代就表示我们重复执行一段代码一次次取出数据的过程,执行一次取一次,他不同与遍历的是,遍历强调的是把数据全部枚举出来逐个进行操作。
迭代器(iterator)?
迭代器就是我们对迭代过程的封装,在不同的语言中有不同的表现形式。在JS中,规定:如果一个对象具有next方法,并且该方法返回一个对象的格式是{value: //值, done: //布尔值}那么这个对象就是一个迭代器
[JavaFX] 纯文本查看 复制代码
const iterator = {
    next: function (){
        return {
            value: 233,
            done: false
        }
    }
}
**其中next方法:用于调用得到下一个数据
调用next方法返回的对象中,value:下一个数据的值。done:布尔值,表示迭代是否结束**
来迭代一个数组看一看:
[JavaScript] 纯文本查看 复制代码
let arr = [3, 5, 7, 8]
let i = 0;
const iterator = {
    next(){
        let result = {
            value: arr,
            done: i >= arr.length
        }
        i++;
        return result
    }
}
iterator.next() //执行一次取出数组中的一个值
迭代器创建
一个函数返回一个迭代器喽。
[JavaScript] 纯文本查看 复制代码
function creatIterator (){
    return {
        next(){
            return {
                value: 23,
                done: fasle
            }
        }
    }
}
我们发现如果一个对象身上有这么一个迭代器生成函数,我们调用它就能返回一个迭代器,然后我们就能愉快的对这个对象进行迭代了,这就是接下来要说的iterable
可迭代协议?
ES6规定,如果一个对象具有知名符号属性Symbol.iterator,并且属性值是一个迭代器创建函数,则该对象是可迭代的(iterable)

看,数组就是一个可迭代对象
执行它

返回了一个迭代器
那么可迭代对象有什么用处呢?
1.可以被 for of 循环遍历
2.可迭代对象可以被展开运算符展开为数组
生成器(generator)
生成器就是迭代器,他的目的就是为了简化迭代器的书写。
如何创建一个生成器呢?通过书写一个生成器函数

执行返回了一个生成器,看next方法,果然也是一个迭代器
怎么用呢?基本用法是
[JavaScript] 纯文本查看 复制代码
function * test () {
    yield 2;
    yield 4;
}
const gene = test()
gene.next() //输出{value: 2, done: false}
gene.next() //输出{value: 4, done: false}
yield关键字就像给迭代暂停标志,规定生成器迭代一次可以走到哪。
举个例子:斐波那契数列
[JavaScript] 纯文本查看 复制代码
function * createFeiboGenerator() {
    let prev2 = 1, //n-2位
        prev1 = 1, //n-1位
        n = 1; //当前位
    while (true) {
        if (n <= 2) {
            yield 1;
        } else {
            const newValue = prev1 + prev2
            yield newValue;
            prev2 = prev1;
            prev1 = newValue;
        }
        n++;
    }
}
const iterator = createFeiboIterator();
还有当我们使用生成器调用next方法进行迭代时是可以传入参数的。
[JavaScript] 纯文本查看 复制代码
function * test (){
    let r1 = yield 2;
    console.log(r1)
    let r2 = yield 4;
    console.log(r2)
    yield 6;
}
const gene = test();

这也很好理解,我们调用一次next方法,生成器函数内部就执行到下一个yield处,参数被当作上一次yield处的返回值了,所以第一次next传值没什么作用。







欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2