除了前2篇文章中描述的可迭代对象以外,在js语言扩展中的生成器对象,也可以作为可迭代对象。
这里用到一个新的关键字yield,该关键字在函数内部使用,用法和return类似,返回函数中的一个值;yield和return区别在于,使用yield的函数“返回”的这个值是可保持内部状态的。(我也没办法用猫的语言表达能力将其表达清楚,如果你懂得ruby之类的动态语言可能早就明白其含义,不明白的见后面的代码吧 :))

任何使用关键字yield的函数(哪怕yield在代码逻辑中是不可达的)都称为“生成器函数”(generator function),生成器函数通过yield返回值。这些函数可以通过return终止函数的执行而不带任何返回值,但不能使用return返回一个值。
然而和普通函数一样,生成器函数也通过关键字function声明,typeof运算符也返回”function”,并且可以从Function.prototype继承属性和方法。要点是:生成器函数调用并不执行生成器函数的函数体,而是返回一个生成器对象!
生成器对象包含一个next()方法,可以恢复生成器函数的执行,直到遇到下一个yield语句为止。这时生成器函数中的yield语句的参数就是next()方法的返回值值,如果生成器函数执行return或者到达函数体的末尾终止,则next()将抛出StopIteration.

function r(min,max){for(let i = Math.ceil(min);i <= max;i++)yield i*i;
}for(let n in r(1,10))console.log(n);

生成器包含一个close()方法,当调用时和它相关的生成器函数就会终止执行,就像在函数运行挂起位置执行了一条return语句。如果当前挂起位置在一个或多个try语句块中,则首先运行finally从句,在执行close()返回。close()没有返回值,但若finally产生了异常则该异常会传播给close();

生成器对象还包括一个send方法,其可以带一个参数,该值将成为yield表达式的值(如果把yield看做语句或函数,则该参数就是语句或函数的返回值);
除了next()和send()之外生成器还有一个throw()方法,如果调用这个方法,yield表达式就将参数作为异常抛给throw(),见如下代码:

function cf(init){let next_v = init;while(true){try{let inc = yield next_v;if(inc)next_v += inc;elsenext_v++;}catch(e){if(e === "reset")next_v = init;elsethrow e;}}
}var c = cf(10);
console.log(c.toString());
console.log(c.next());
console.log(c.send(10));
console.log(c.throw("reset")); //next_v == 10;
console.log(c.next());//我们可以让reset稍微优雅点
c.reset = function(){return this.throw("reset");
}/*but Generator is not defined!!!
注释中的代码会报错!!!
Generator.prototype.reset = function(){return this.throw("reset");
}
*/console.log(c.reset());

javascript语言扩展:可迭代对象(3)相关推荐

  1. 入门前端-《JavaScript 语言入门教程-实例对象和New对象》

    new 命令的原理 使用new命令时,它后面的函数依次执行下面的步骤. 创建一个空对象,作为将要返回的对象实例. 将这个空对象的原型,指向构造函数的prototype属性. 将这个空对象赋值给函数内部 ...

  2. ebnf描述c语言语句结构,EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构;并用操作语义的方法描述对应的语义规则...

    Presentation on theme: "EBNF与操作语义 请用扩展的 BNF 描述 javascript语言里语句的结构:并用操作语义的方法描述对应的语义规则"- Pre ...

  3. JavaScript 可迭代对象

    Javascript 可迭代对象 小插曲 我之前学到了对象与数组进行拼接,如果对象不加 [Symbol.isConcatSpreadable]:true,对象不会当作数组处理,反之,对象的元素将会像数 ...

  4. JavaScript 迭代器 迭代对象

    1.什么是迭代器? --------------------------------------什么是迭代器?         迭代器(iterator),是确使用户可在容器对象(container, ...

  5. JavaScript语言精粹:对象——读书笔记

    1 对象 简单数据类型 number string boolean null undefined 对象类型 array function regularExpression object 对象简介 可 ...

  6. 怎么确定迭代器后面还有至少两个值_JS Lazy evaluation:可迭代对象与迭代器

    本文已经过原作者 MelkorNemesis 授权翻译. Lazy evaluation Lazy evaluation常被译为"延迟计算"或"惰性计算",指的 ...

  7. 使用Firebug或chrome-devToolBar深入学习javascript语言核心

    使用Firebug和chrome-devToolBar调试页面样式或脚本是前端开发每天必做之事.这个开发神器到底能给我们带来哪些更神奇的帮助呢?这几天看的一些资料中给了我启发,能不通过Firebug和 ...

  8. python input输入多个变量_「Python 秘籍」1.2 解压可迭代对象赋值给多个变量

    问题 需要从某个可迭代对象中分解出 N 个元素,但是这个可迭代对象的长度可能超过 N,这会导致出现"需要解包的值过多(too many values to unpack)"的异常. ...

  9. python中可迭代对象拆包时、怎么赋值给占位符_python3-数据结构和算法 » 1.2 解压可迭代对象赋值给多个变量...

    1.2 解压可迭代对象赋值给多个变量 问题 如果一个可迭代对象的元素个数超过变量个数时,会抛出一个 ValueError . 那么怎样才能从这个可迭代对象中解压出 N 个元素出来? 解决方案 Pyth ...

最新文章

  1. 手把手教你ARC——iOS/Mac开发ARC入门和使用
  2. Android_Servlet验证的简单登录程序
  3. 【深度学习】网络架构设计:CNN based和Transformer based
  4. 四面阿里,看看你都会吗
  5. 吴颖二:12.27 午评 地缘政治一波未平一波又起,千三可到?
  6. 安全强化linux-SELinux
  7. arm-linux-gcc 和Makefile
  8. Html.Partial vs Html.RenderPartial&Html.Action vs Html.RenderAction
  9. Highlighter与BooleanQuery查询
  10. filenet安装-总结安装一天的成果
  11. SQL的连接查询——内连接、左连接、右连接、自连接(重要)
  12. 关于U盘病毒autorun.inf更改文件夹属性为系统文件夹并隐藏文件夹
  13. day02-2学习过程笔记
  14. 软件测试职业发展方向
  15. excel如何根据身份证批量提取员工年龄?
  16. springboot 调用方法事物_springboot中使用@Transactional注解事物不生效的坑
  17. 联想微型计算机2010年,2010年10月自考02277微型计算机原理及应用真题及答案
  18. Android Studio 生成二维码、生成带logo的二维码
  19. 【18】CSS基础(3)——理解层叠式
  20. 求解马走棋问题(回溯法)

热门文章

  1. java24小时运行一次_使用crontab每分钟执行一次脚本,每24小时执行一次脚本[关闭]...
  2. 学习vue3系列ref
  3. ES6之let能替代var吗?
  4. python控件随窗口变化而适配_python pyqt5 设置控件随窗体拉伸
  5. oracle对象依赖关系图,Oracle concepts 学习笔记(4)——Schema对象间的依赖关系
  6. php图片滑动代码,基于mootools 1.3框架下的图片滑动效果代码_Mootools
  7. 安卓判断服务器返回的状态码,关于服务器返回的十四种常见HTTP状态码详解
  8. MySQL外键没作用_MySQL 外键索引不生效
  9. oracle和mysql使用区别大吗_Oracle和MySQL在使用上的区别
  10. Oracle密码过期ORA-28001