Skip to content

Commit 6f98097

Browse files
committed
edit generator
1 parent 1b0805c commit 6f98097

File tree

2 files changed

+111
-58
lines changed

2 files changed

+111
-58
lines changed

docs/generator.md

Lines changed: 68 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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+
685702
for (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
697746
let 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
// 下面是二叉树的构造函数,

docs/object.md

Lines changed: 43 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -5,27 +5,31 @@
55
ES6允许直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。
66

77
```javascript
8-
// 示例一
98
var foo = 'bar';
109
var baz = {foo};
10+
baz // {foo: "bar"}
11+
1112
// 等同于
1213
var baz = {foo: foo};
14+
```
1315

14-
baz // Object {foo: "bar"}
16+
上面代码表明,ES6允许在对象之中,只写属性名,不写属性值。这时,属性值等于属性名所代表的变量。下面是另一个例子。
1517

16-
// 示例二
18+
```javascript
1719
function f(x, y) {
1820
return {x, y};
1921
}
22+
2023
// 等同于
24+
2125
function f(x, y) {
2226
return {x: x, y: y};
2327
}
2428

2529
f(1, 2) // Object {x: 1, y: 2}
2630
```
2731

28-
上面代码表明,ES6允许在对象之中,只写属性名。这时,属性值等于属性名所代表的变量。除了属性简写,方法也可以简写。
32+
除了属性简写,方法也可以简写。
2933

3034
```javascript
3135
var o = {
@@ -72,23 +76,6 @@ getPoint()
7276
// {x:1, y:10}
7377
```
7478

75-
赋值器和取值器,也可以采用简洁写法。
76-
77-
```javascript
78-
var cart = {
79-
_wheels: 4,
80-
get wheels () {
81-
return this._wheels
82-
},
83-
set wheels (value) {
84-
if (value < this._wheels) {
85-
throw new Error('hey, come back here!')
86-
}
87-
this._wheels = value
88-
}
89-
}
90-
```
91-
9279
模块输出变量,就非常合适使用简洁写法。
9380

9481
```javascript
@@ -107,6 +94,41 @@ function clear () {
10794
}
10895

10996
module.exports = { getItem, setItem, clear };
97+
// 等同于
98+
module.exports = {
99+
getItem: getItem,
100+
setItem: setItem,
101+
clear: clear
102+
};
103+
```
104+
105+
属性的赋值器(setter)和取值器(getter),事实上也是采用这种写法。
106+
107+
```javascript
108+
var cart = {
109+
_wheels: 4,
110+
111+
get wheels () {
112+
return this._wheels;
113+
},
114+
115+
set wheels (value) {
116+
if (value < this._wheels) {
117+
throw new Error('数值太小了!');
118+
}
119+
this._wheels = value;
120+
}
121+
}
122+
```
123+
124+
如果某个方法的值是一个Generator函数,前面需要加上星号。
125+
126+
```javascript
127+
var obj = {
128+
* m(){
129+
yield 'hello world';
130+
}
131+
}
110132
```
111133

112134
## 属性名表达式

0 commit comments

Comments
 (0)