javascript语言扩展:可迭代对象(3)

来源:互联网 发布:生理学软件 编辑:程序博客网 时间:2024/05/16 08:07

除了前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());
0 0
原创粉丝点击