ES6新特性三: Generator(生成器)函数详解

 更新时间:2017年04月21日 08:48:59   作者:Dason_yu  
这篇文章主要介绍了ES6新特性之Generator(生成器)函数,简单分析了Generator(生成器)函数的功能、定义、调用方法并结合实例形式给出了相关使用技巧,需要的朋友可以参考下

本文实例讲述了ES6新特性三: Generator(生成器)函数。分享给大家供大家参考,具体如下:

1. 简介

① 理解:可以把它理解成一个函数的内部状态的遍历器,每调用一次,函数的内部状态发生一次改变。

② 写法:

function* f() {}

③ 作用:就是可以完全控制函数的内部状态的变化,依次遍历这些状态。

④ 运行过程:当调用Generator函数的时候,该函数并不执行,而是返回一个遍历器(可以理解成暂停执行)。通过调用next()开始执行,遇到yield停止执行,返回一个value属性值为当前yield语句的值,done属性为false的对象,循环调用next(),一直执行到return语句(如果没有return语句,就执行到函数结束)。next方法返回的对象的value属性,就是紧跟在return语句后面的表达式的值(如果没有return语句,则value属性的值为undefined),done属性的值true,表示遍历已经结束。

示例:

function* helloWorldGenerator() {
 yield 'hello';
 yield 'world';
 return 'ending';
}
var hw = helloWorldGenerator();//第一次调用该方法不会执行,仅返回一个遍历器。
var a = hw.next();
while(!a.done){ //当执行到return 时,a.done=true,终止循环
 console.log(a.value+','+a.done);
 a = hw.next();
}
console.log(a.value+','+a.done);

结果:

hello,false
world,false
ending,true

2. next() 的参数

① 我们要知道是next()返回一个对象,yield语句本身是没有返回值,或者说总是返回undefined。next方法可以带一个参数,该参数就会被当作上一个yield语句的返回值

function* f() {
 for(var i=0; true; i++) {
  var reset = yield i;
  console.log(reset); //打印reset,验证yield语句是没有返回值的
  if(reset) { i = -1; }
 }
}
var g = f();
console.log(g.next()) // { value: 0, done: false }
console.log(g.next())// { value: 1, done: false }
console.log(g.next(true)) // { value: 0, done: false }

结果:

{ value: 0, done: false }
undefined
{ value: 1, done: false }
true
{ value: 0, done: false }

通过next方法的参数,就有办法在Generator函数开始运行之后,继续向函数体内部注入值。也就是说,可以在Generator函数运行的不同阶段,从外部向内部注入不同的值,从而调整函数行为。

②由于next方法的参数表示上一个yield语句的返回值,所以第一次使用next方法时,不能带有参数。V8引擎直接忽略第一次使用next方法时的参数,只有从第二次使用next方法开始,参数才是有效的。

function* foo(x) {
 var y = 2 * (yield (x + 1));
 var z = yield (y / 3);
 return (x + y + z);
}
var it = foo(5);
console.log(it.next(3))// { value:6, done:false }
console.log(it.next(12))// { value:8, done:false }
console.log(it.next(13))// { value:42, done:true }

3. for-of 遍历generator

for...of循环可以自动遍历Generator函数,且此时不再需要调用next方法,

一旦next方法的返回对象的done属性为true,for...of循环就会中止,且不包含该返回对象

function *foo() {
 yield 1;
 yield 2;
 yield 3;
 yield 4;
 yield 5;
 return 6;
}
for (let v of foo()) {
 console.log(v);
}
// 1 2 3 4 5

4. yield* 语句

① 如果yield命令后面跟的是一个遍历器,需要在yield命令后面加上星号,表明它返回的是一个遍历器。这被称为yield*语句。

let a = (function* () {
 yield 'Hello!';
 yield 'Bye!';
}());
let b = (function* () {
 yield 'Greetings!';
 yield* a;
 yield 'Ok, bye.';
}());
for(let value of b) {
 console.log(value);
}

结果:

Greetings!
Hello!
Bye!
Ok, bye.

② yield命令后面如果不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器。

function* gen(){
 yield* ["a", "b", "c"];
}
gen().next() // { value:"a", done:false }

遍历嵌套数组:

function* iterTree(tree) {
 if (Array.isArray(tree)) {
 for(let i=0; i < tree.length; i++) {
  yield* iterTree(tree[i]);
 }
 } else {
 yield tree;
 }
}
const tree = [ 'a', ['b', 'c'], ['d', 'e'] ];
for(let x of iterTree(tree)) {
 console.log(x);
}// a b c d e

希望本文所述对大家ECMAScript程序设计有所帮助。

相关文章

  • Uni-app跨平台开发应用入门实战

    Uni-app跨平台开发应用入门实战

    这篇文章主要为大家介绍了Uni-app跨平台开发应用入门实战示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-03-03
  • Webpack的Loader和Plugin的区别

    Webpack的Loader和Plugin的区别

    这篇文章主要介绍了Webpack的Loader和Plugin的区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-11-11
  • 分页栏的web标准实现

    分页栏的web标准实现

    分页栏是网页上最常见不过的一个组件,本博文给出分页栏的一个web2.0标准示例,并作简要分析
    2011-11-11
  • JS实现浏览器状态栏显示时间的方法

    JS实现浏览器状态栏显示时间的方法

    这篇文章主要介绍了JS实现浏览器状态栏显示时间的方法,涉及JavaScript针对时间及状态栏操作的相关技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • JS实现即点即编辑功能代码

    JS实现即点即编辑功能代码

    以前在网上都看到过类似的功能,不过没自己想要实现过,这次刚好做静态页面中有这样的一个需求,就试着自己做做看,做完发现也不是什么很难的事情。
    2008-10-10
  • select每选择一个option选项减少对应的option实现方法

    select每选择一个option选项减少对应的option实现方法

    这篇文章主要为大家介绍了select每选择一个option选项减少对应的option实现方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-12-12
  • JS Html转义和反转义(html编码和解码)的实现与使用方法总结

    JS Html转义和反转义(html编码和解码)的实现与使用方法总结

    这篇文章主要介绍了JS Html转义和反转义(html编码和解码)的实现与使用方法,结合实例形式总结分析了JS Html转义和反转义、html编码和解码相关封装类定义与具体使用技巧,需要的朋友可以参考下
    2020-03-03
  • js获取select默认选中的Option并不是当前选中值

    js获取select默认选中的Option并不是当前选中值

    这篇文章主要介绍了js如何获取select默认选中的Option并不是当前选中的值,需要的朋友可以参考下
    2014-05-05
  • 使用javascript为网页增加夜间模式

    使用javascript为网页增加夜间模式

    如何给Web页面增加夜间模式功能? 其实所谓的夜间模式就是在页面上增加一个透明的遮罩层,但是遮罩层会挡住页面元素, 解决方法是 添加DIV,给DIV的outline属性一个很大的outline-width值,用outline的边框作为遮罩,这样既能正常点击页面元素,又能达到夜间模式的效果
    2014-01-01
  • javascript中checkbox使用方法简单实例演示

    javascript中checkbox使用方法简单实例演示

    这篇文章通过简单的实例演示了javascript中checkbox使用方法,感兴趣的小伙伴们可以参考一下
    2015-11-11

最新评论