首页 > 其他 > 详细

Generator函数和可迭代对象相关概念

时间:2020-09-25 18:59:03      阅读:32      评论:0      收藏:0      [点我收藏+]

生成器函数(通过function*定义的函数,也就是Generator函数)

1.调用一个生成器函数,并不会马上执行它里面的语句,而是返回这个生成器迭代器(iterator)对象

2.调用迭代器的next()方法,会执行到第一个出现yield的位置,返回yield后面的值,然后暂停。如果遇到yield*,则执行权移交给另外一个生成器函数(当前的暂停)。

3.next()方法的返回值为一个对象({value: yield语句后面的值, done: 布尔值,是否还有yield语句})。

4.next()方法可以传参,参数值赋给上一条yield语句左边的变量

function* gen() {
    yield ‘hello‘;
    var x = yield ‘world‘;
    yield x;
}
var g = gen();
console.log(g.next());  //  {value: ‘hello‘, done: false}
console.log(g.next());  //  {value: ‘world‘, done: false}
console.log(g.next(‘nice‘));  //  {value: ‘nice‘, done: false}
console.log(g.next());  //  {value: undefined, done: true}

5.return语句会导致生成器立即变为完成状态,使用next()返回的对象的done为true,return后面的返回值作为当前next()返回的value值。

function* gen() {
    yield ‘hello‘;
    return ‘world‘;
    yield ‘nice‘;
}
var g = gen();
console.log(g.next())	//{value: ‘hello‘, done: false}
console.log(g.next())	//{value: ‘world‘, done: true}
console.log(g.next())	//{value: undefined, done: true}

6.生成器也可以接收参数。

function* idMaker() {
    var index = arguments[0] || 0;
    while (true)
        yield index++;
}
var gen = idMaker(4);
console.log(gen.next().value)	//4
console.log(gen.next().value)	//5

7.yield*的使用。

function* anotherGenerator(i) {
    yield i + 1;
    yield i + 2;
}
function* generator(i) {
    yield i;
    yield* anotherGenerator(i);	//移交执行权
    yield i + 10;
}
var gen = generator(10);
console.log(gen.next());	//10
console.log(gen.next());	//11
console.log(gen.next());	//12
console.log(gen.next());	//20

8.生成器函数的经典应用——多维数组扁平化

var arr = [[1, 2, 2],[3, 4, 5, 5],[6, 7, 8, 9, [11, 12, [12, 13, [14]]]], 10];
function* flat(array) {
    for (const i of array) {
        if (typeof i !== ‘number‘) {
            yield* flat(i);
        } else {
            yield i;
        }
    }
}
var gen = flat(arr);
var flatArr = [...gen];
console.log(flatArr)
//[1, 2, 2, 3, 4, 5, 5, 6, 7, 8, 9, 11, 12, 12, 13, 14, 10]

可迭代对象

1.内置可迭代对象有:String、Array、TypedArray、Set、Map。
2.要想成为可迭代对象,必须实现@@iterator方法。意味着对象(或它原型链上的某个对象)必须有一个键为@@iterator的属性,可以通过常量Symbol.iterator访问该属性。下面是自定义可迭代对象的例子。

var myIterable = {};
myIterable[Symbol.iterator] = function* () {
    yield 1;
    yield 2;
}
console.log([...myIterable])	//[1, 2]

3.当一个对象需要被迭代的时候(比如被置入一个for...of循环),首先会不带参数调用它的@@iterator方法,然后用此方法返回的迭代器获取要迭代的值。

4.可以通过提供自己的@@iterator方法,重新定义内置可迭代对象的默认迭代行为。

var myString = new String(‘hi‘);
myString[Symbol.iterator] = function () {
    return {
        first: true,
        next: function () {
            if (this.first) {
                return { value: ‘hello‘, done: false }
            } else {
                return { done: true }
            }
        }
    }
}
console.log([...myString]);	//[hello]
console.log(myString + ‘‘);	//hi

5.for...of循环、展开语法、yield*、和解构赋值,都需要可迭代对象。

6.生成器对象(生成器函数的返回值)既是一个迭代器,也是一个可迭代对象

Generator函数和可迭代对象相关概念

原文:https://www.cnblogs.com/gongming/p/13731556.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!