javascript语言扩展:可迭代对象(3)
除了前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;
else
next_v++;
}
catch(e){
if(e === "reset")
next_v = init;
else
throw 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)的更多相关文章
- javascript语言扩展:可迭代对象(1)
在ECMAScript中我们知道可以通过for in语句进行对象属性的遍历,当然这些属性不包括继承而来的属性: var ary = [1,2,3,"aa",4]; for(i in ...
- javascript语言扩展:可迭代对象(2)
在文章迭代器(1)中我们简单介绍了如何创建一个可迭代对象:出于某种考虑你可能想从可迭代对象中显式获取一个迭代器对象,这时你可以调用Iterator()函数(该函数是定义在JavaScript 1.7中 ...
- javascript语言扩展:可迭代对象(5)
文章1-4篇说的都是js中的可迭代对象,下面让我们看看ruby中的等价物. 不可否认,ruby中对于迭代器和生成器的语法都相当简洁:ruby从一开始就有一个简洁的基因,而js后来的不断扩充使得其有些语 ...
- javascript语言扩展:可迭代对象(4)
js 1.7中还包含一个数组推导(array comprehension)的特性,如果不在最后介绍它好像显得不怎么完整. 数组推导其实很简单: let a = [x*x for(x in range( ...
- Python Cookbook(第3版)中文版:15.20 处理C语言中的可迭代对象
15.20 处理C语言中的可迭代对象¶ 问题¶ 你想写C扩展代码处理来自任何可迭代对象如列表.元组.文件或生成器中的元素. 解决方案¶ 下面是一个C扩展函数例子,演示了怎样处理可迭代对象中的元素: s ...
- python 迭代器(一):迭代器基础(一) 语言内部使用 iter(...) 内置函数处理可迭代对象的方式
简介 在 Python 中,所有集合都可以迭代.在 Python 语言内部,迭代器用于支持: 1.for 循环2.构建和扩展集合类型3.逐行遍历文本文件4.列表推导.字典推导和集合推导5.元组拆包6. ...
- 扩展javascript扩展(类,对象,原型)
扩展javascript扩展(类,对象,原型)
- JavaScript中对象与函数的某些事[JavaScript语言精粹-N1]
今天在读<JavaScript语言精粹>的时候,关于函数的一个部分,始终觉得有点难以理解,代码如下: 1: var obj = (function(){ 2: var value = 0; ...
- JavaScript语言精粹之对象
用object.hasOwnProperty(variable)来确定这个属性名是否为该对象成员,还是来自于原型链. for(my in obj){ if(obj.hasOwnProperty(my) ...
随机推荐
- [virtualenv]生产环境中使用virtualenv
virtualenv 对于python开发和部署都是好工具,可以隔离多个python版本和第三方库的版本,这里作者总结了几个常用python服务怎么样结合virtual部署 原文链接 Python 中 ...
- 剑指Offer——简述堆和栈的区别
剑指Offer--简述堆和栈的区别 堆(Heap) Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建: Java虚拟机规范描述:所有的对象实例及数组都要在堆上分配: Java堆可以处于物理 ...
- 【iOS 开发】基本 UI 控件详解 (UIButton | UITextField | UITextView | UISwitch)
博客地址 : http://blog.csdn.net/shulianghan/article/details/50051499 ; 一. UI 控件简介 1. UI 控件分类 UI 控件分类 : 活 ...
- Qt中事件分发源代码剖析
Qt中事件分发源代码剖析 Qt中事件传递顺序: 在一个应该程序中,会进入一个事件循环,接受系统产生的事件,并且进行分发,这些都是在exec中进行的. 下面举例说明: 1)首先看看下面一段示例代码: i ...
- linux目录间的瞬间转移:dtags
http://blog.csdn.net/pipisorry/article/details/50923957 linux下dtags的安装 apt-get install python3-pip # ...
- UNIX网络编程——分析一帧基于UDP的TFTP协议帧
下图是UDP的段格式: 相比TCP段格式,UDP要简单得多,也没啥好说的,需要注意的是UDP数据长度指payload加上首部的长度. 下面分析一帧基于UDP的TFTP协议帧: 以太网首部 0000: ...
- 高性能nosql ledisdb设计与实现 (2):replication
ledisdb现在已经支持replication机制,为ledisdb的高可用做出了保障. 使用 假设master的ip为10.20.187.100,端口6380,slave的ip为10.20.187 ...
- 【一天一道LeetCode】#112. Path Sum
一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given a ...
- SHA算法
安全Hash函数(SHA)是使用最广泛的Hash函数.由于其他曾被广泛使用的Hash函数都被发现存在安全隐患,从2005年至今,SHA或许是仅存的Hash算法标准. SHA发展史 SHA由美国标准与技 ...
- golang:一个高性能低精度timer实现
在go自带的timer实现中,采用的是通常的最小堆的方式,具体可以参见这里. 最小堆能够提供很好的定时精度,但是,在实际情况中,我们并不需要这样高精度的定时器,譬如对于一个连接,如果它在2分钟以内没有 ...