@@ -94,7 +94,7 @@ setTimeout(function () {
9494}, 2000 );
9595```
9696
97- 上面代码中,函数f如果是普通函数 ,在为变量generator赋值时就会执行。但是,函数f是一个Generator函数,就变成只有调用next方法时,函数f才会执行 。
97+ 上面代码中,函数 ` f ` 如果是普通函数 ,在为变量generator赋值时就会执行。但是,函数 ` f ` 是一个Generator函数,就变成只有调用 ` next ` 方法时,函数 ` f ` 才会执行 。
9898
9999另外需要注意,yield语句不能用在普通函数中,否则会报错。
100100
@@ -246,7 +246,7 @@ it.next(13)
246246// { value:42, done:true }
247247` ` `
248248
249- 上面代码第一次调用next方法时 ,返回` x+ 1 ` 的值6;第二次调用` next` 方法,将上一次` yield ` 语句的值设为12,因此` y` 等于24,返回` y / 3 ` 的值8;第三次调用` next` 方法,将上一次` yield ` 语句的值设为13,因此` z` 等于13,这时` x` 等于5,` y` 等于24,所以` return ` 语句的值等于42。
249+ 上面代码第一次调用 ` next ` 方法时 ,返回` x+ 1 ` 的值6;第二次调用` next` 方法,将上一次` yield ` 语句的值设为12,因此` y` 等于24,返回` y / 3 ` 的值8;第三次调用` next` 方法,将上一次` yield ` 语句的值设为13,因此` z` 等于13,这时` x` 等于5,` y` 等于24,所以` return ` 语句的值等于42。
250250
251251注意,由于` next` 方法的参数表示上一个` yield ` 语句的返回值,所以第一次使用` next` 方法时,不能带有参数。V8引擎直接忽略第一次使用` next` 方法时的参数,只有从第二次使用` next` 方法开始,参数才是有效的。
252252
@@ -414,7 +414,7 @@ try {
414414// 外部捕获 [Error: a]
415415` ` `
416416
417- 上面代码之所以只捕获了a ,是因为函数体外的catch语句块,捕获了抛出的a错误以后 ,就不会再继续执行try语句块了。
417+ 上面代码之所以只捕获了 ` a ` ,是因为函数体外的catch语句块,捕获了抛出的 ` a ` 错误以后 ,就不会再继续执行try语句块了。
418418
419419如果Generator函数内部没有部署try...catch代码块,那么throw方法抛出的错误,将被外部try...catch代码块捕获。
420420
@@ -438,7 +438,7 @@ try {
438438// 外部捕获 a
439439` ` `
440440
441- 上面代码中,遍历器函数g内部 ,没有部署try...catch代码块,所以抛出的错误直接被外部catch代码块捕获。
441+ 上面代码中,遍历器函数 ` g ` 内部 ,没有部署try...catch代码块,所以抛出的错误直接被外部catch代码块捕获。
442442
443443如果Generator函数内部部署了try...catch代码块,那么遍历器的throw方法抛出的错误,不影响下一次遍历,否则遍历直接终止。
444444
@@ -682,6 +682,23 @@ function* bar() {
682682 yield ' y' ;
683683}
684684
685+ // 等同于
686+ function * bar () {
687+ yield ' x' ;
688+ yield ' a' ;
689+ yield ' b' ;
690+ yield ' y' ;
691+ }
692+
693+ // 等同于
694+ function * bar () {
695+ yield ' x' ;
696+ for (let v of foo ()) {
697+ console .log (v);
698+ }
699+ yield ' y' ;
700+ }
701+
685702for (let v of bar ()){
686703 console .log (v);
687704}
@@ -691,7 +708,39 @@ for (let v of bar()){
691708// "y"
692709` ` `
693710
694- 从另一个角度看,如果` yield ` 命令后面跟的是一个遍历器对象,需要在` yield ` 命令后面加上星号,表明它返回的是一个遍历器对象。这被称为` yield * ` 语句。
711+ 再来看一个对比的例子。
712+
713+ ` ` ` javascript
714+ function * inner () {
715+ yield ' hello!' ;
716+ }
717+
718+ function * outer1 () {
719+ yield ' open' ;
720+ yield inner ();
721+ yield ' close' ;
722+ }
723+
724+ var gen = outer1 ()
725+ gen .next ().value // "open"
726+ gen .next ().value // 返回一个遍历器对象
727+ gen .next ().value // "close"
728+
729+ function * outer2 () {
730+ yield ' open'
731+ yield * inner ()
732+ yield ' close'
733+ }
734+
735+ var gen = outer2 ()
736+ gen .next ().value // "open"
737+ gen .next ().value // "hello!"
738+ gen .next ().value // "close"
739+ ` ` `
740+
741+ 上面例子中,` outer2` 使用了` yield * ` ,` outer1` 没使用。结果就是,` outer1` 返回一个遍历器对象,` outer2` 返回该遍历器对象的内部值。
742+
743+ 从语法角度看,如果` yield ` 命令后面跟的是一个遍历器对象,需要在` yield ` 命令后面加上星号,表明它返回的是一个遍历器对象。这被称为` yield * ` 语句。
695744
696745` ` ` javascript
697746let delegatedIterator = (function * () {
@@ -738,49 +787,31 @@ function* concat(iter1, iter2) {
738787
739788上面代码说明,` yield * ` 不过是` for ... of` 的一种简写形式,完全可以用后者替代前者。
740789
741- 再来看一个对比的例子 。
790+ 如果 ` yield * ` 后面跟着一个数组,由于数组原生支持遍历器,因此就会遍历数组成员 。
742791
743792` ` ` javascript
744- function * inner () {
745- yield ' hello!' ;
746- }
747-
748- function * outer1 () {
749- yield ' open' ;
750- yield inner ();
751- yield ' close' ;
752- }
753-
754- var gen = outer1 ()
755- gen .next ().value // "open"
756- gen .next ().value // 返回一个遍历器对象
757- gen .next ().value // "close"
758-
759- function * outer2 () {
760- yield ' open'
761- yield * inner ()
762- yield ' close'
793+ function * gen (){
794+ yield * [" a" , " b" , " c" ];
763795}
764796
765- var gen = outer2 ()
766- gen .next ().value // "open"
767- gen .next ().value // "hello!"
768- gen .next ().value // "close"
797+ gen ().next () // { value:"a", done:false }
769798` ` `
770799
771- 上面例子中, ` outer2 ` 使用了 ` yield * ` , ` outer1 ` 没使用。结果就是, ` outer1 ` 返回一个遍历器对象, ` outer2 ` 返回该遍历器对象的内部值 。
800+ 上面代码中, ` yield ` 命令后面如果不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器对象 。
772801
773- 如果 ` yield * ` 后面跟着一个数组,由于数组原生支持遍历器,因此就会遍历数组成员 。
802+ 实际上,任何数据结构只要有Iterator接口,就可以被 ` yield * ` 遍历 。
774803
775804` ` ` javascript
776- function * gen (){
777- yield * [" a" , " b" , " c" ];
778- }
805+ let read = (function * () {
806+ yield ' hello' ;
807+ yield * ' hello' ;
808+ })();
779809
780- gen ().next () // { value:"a", done:false }
810+ read .next ().value // "hello"
811+ read .next ().value // "h"
781812` ` `
782813
783- 上面代码中,` yield ` 命令后面如果不加星号,返回的是整个数组,加了星号就表示返回的是数组的遍历器对象 。
814+ 上面代码中,` yield ` 语句返回整个字符串, ` yield * ` 语句返回单个字符。因为字符串具有Iterator接口,所以被 ` yield * ` 遍历 。
784815
785816如果被代理的Generator函数有` return ` 语句,那么就可以向代理它的Generator函数返回数据。
786817
@@ -840,7 +871,7 @@ for(let x of iterTree(tree)) {
840871// e
841872` ` `
842873
843- 下面是一个稍微复杂的例子,使用yield* 语句遍历完全二叉树。
874+ 下面是一个稍微复杂的例子,使用 ` yield * ` 语句遍历完全二叉树。
844875
845876` ` ` javascript
846877// 下面是二叉树的构造函数,
0 commit comments