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.生成器对象(生成器函数的返回值)既是一个迭代器,也是一个可迭代对象。
原文:https://www.cnblogs.com/gongming/p/13731556.html