17
17
- [ Maps] ( #maps )
18
18
- [ WeakMaps] ( #weakmaps )
19
19
- [ Promises] ( #promises )
20
+ - [ Generators] ( #generators )
21
+ - [ Async Await] ( #async-await )
20
22
21
23
## var versus let / const
22
24
@@ -67,7 +69,7 @@ let x = 'hi'; // ReferenceError: x is not defined
67
69
68
70
> ** 最佳实践** : 在重构老代码时,` var ` 声明需要格外的注意。在创建一个新项目时,使用 ` let ` 声明一个变量,使用 ` const ` 来声明一个不可改变的常量。
69
71
70
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
72
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
71
73
72
74
## Replacing IIFEs with Blocks
73
75
@@ -92,7 +94,7 @@ console.log(food); // Reference Error
92
94
console .log (food); // Reference Error
93
95
```
94
96
95
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
97
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
96
98
97
99
## Arrow Functions
98
100
@@ -181,7 +183,7 @@ const squares = arr.map(x => x * x); // Arrow Function for terser implementation
181
183
182
184
> ** 最佳实践** :尽可能地多使用 ** 箭头函数** 。
183
185
184
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
186
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
185
187
186
188
## Strings
187
189
@@ -291,7 +293,7 @@ let today = new Date();
291
293
let text = ` The time and date is ${ today .toLocaleString ()} ` ;
292
294
```
293
295
294
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
296
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
295
297
296
298
## Destructuring
297
299
@@ -318,7 +320,7 @@ console.log(b); // 2
318
320
319
321
### Destructuring Objects
320
322
321
- ** 结构对象 **
323
+ ** 解构对象 **
322
324
323
325
``` javascript
324
326
var luke = { occupation: ' jedi' , father: ' anakin' };
@@ -334,7 +336,7 @@ console.log(occupation); // 'jedi'
334
336
console .log (father); // 'anakin'
335
337
```
336
338
337
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
339
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
338
340
339
341
## Modules
340
342
@@ -458,7 +460,7 @@ const { Component, PropTypes } = React;
458
460
> ** 注意** :被导出的值是被 ** 绑定的(原文:bingdings)** ,而不是引用。
459
461
所以,改变一个模块中的值的话,会影响其他引用本模块的代码,一定要避免此种改动发生。
460
462
461
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
463
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
462
464
463
465
## Parameters
464
466
@@ -553,7 +555,7 @@ function initializeCanvas(
553
555
Math .max (... [- 1 , 100 , 9001 , - 32 ]); // 9001
554
556
```
555
557
556
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
558
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
557
559
558
560
## Classes
559
561
@@ -623,7 +625,7 @@ class Personal extends Person {
623
625
624
626
> ** 最佳实践** :ES6新的类语法把我们从晦涩难懂的实现和原型操作中解救出来,这是个非常适合初学者的功能,而且能让我们写出更干净整洁的代码。
625
627
626
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
628
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
627
629
628
630
## Symbols
629
631
@@ -643,7 +645,7 @@ object[keyTwo] = 'Much Uniqueness';
643
645
>> false
644
646
```
645
647
646
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
648
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
647
649
648
650
## Maps
649
651
@@ -700,10 +702,11 @@ for (let [key, value] of map.entries()) {
700
702
}
701
703
```
702
704
703
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
705
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
704
706
705
707
## WeakMaps
706
708
709
+
707
710
In order to store private data in < ES5, we had various ways of doing this.
708
711
One such method was using naming conventions:
709
712
@@ -771,7 +774,7 @@ value = map.get(el); // undefined
771
774
> ** 提示** :结合这个例子,再考虑下jQuery是如何实现缓存带有引用的DOM元素这个功能的,使用了WeakMaps的话,当被缓存的DOM元素被移除的时,jQuery可以自动释放相应元素的内存。
772
775
通常情况下,在涉及DOM元素存储和缓存的情况下,使用WeakMaps是非常适合的。
773
776
774
- <sup >[ (back to table of contents )] ( #table-of-contents ) </sup >
777
+ <sup >[ (回到目录 )] ( #table-of-contents ) </sup >
775
778
776
779
## Promises
777
780
@@ -849,3 +852,136 @@ Promise.all(urlPromises)
849
852
console .log (' Failed: ' , err);
850
853
});
851
854
```
855
+
856
+ <sup >[ (回到目录)] ( #table-of-contents ) </sup >
857
+
858
+ ## Generators
859
+
860
+ Similar to how [ Promises] ( https://github.com/DrkSephy/es6-cheatsheet#promises ) allow us to avoid
861
+ [ callback hell] ( http://callbackhell.com/ ) , Generators allow us to flatten our code - giving our
862
+ asynchronous code a synchronous feel. Generators are essentially functions which we can
863
+ [ pause their excution] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/yield )
864
+ and subsequently return the value of an expression.
865
+
866
+ A simple example of using generators is shown below:
867
+
868
+ ``` javascript
869
+ function * sillyGenerator () {
870
+ yield 1 ;
871
+ yield 2 ;
872
+ yield 3 ;
873
+ yield 4 ;
874
+ }
875
+
876
+ var generator = sillyGenerator ();
877
+ var value = generator .next ();
878
+ > console .log (value); // { value: 1, done: false }
879
+ > console .log (value); // { value: 2, done: false }
880
+ > console .log (value); // { value: 3, done: false }
881
+ > console .log (value); // { value: 4, done: false }
882
+ ```
883
+
884
+ Where [ next] ( https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Generator/next )
885
+ will allow us to push our generator forward and evaluate a new expression. While the above example is extremely
886
+ contrived, we can utilize Generators to write asynchronous code in a synchronous manner:
887
+
888
+ ``` javascript
889
+ // Hiding asynchronousity with Generators
890
+
891
+ function request (url ) {
892
+ getJSON (url, function (response ) {
893
+ generator .next (response);
894
+ });
895
+ }
896
+ ```
897
+
898
+ And here we write a generator function that will return our data:
899
+
900
+ ``` javascript
901
+ function * getData () {
902
+ var entry1 = yield request (' http://some_api/item1' );
903
+ var data1 = JSON .parse (entry1);
904
+ var entry2 = yield request (' http://some_api/item2' );
905
+ var data2 = JSON .parse (entry2);
906
+ }
907
+ ```
908
+
909
+ By the power of ` yield ` , we are gauranteed that ` entry1 ` will have the data needed to be parsed and stored
910
+ in ` data1 ` .
911
+
912
+ While generators allow us to write asynchronous code in a synchronous manner, there is no clear
913
+ and easy path for error propagation. As such, as we can augment our generator with Promises:
914
+
915
+ ``` javascript
916
+ function request (url ) {
917
+ return new Promise ((resolve , reject ) => {
918
+ getJSON (url, resolve);
919
+ });
920
+ }
921
+ ```
922
+
923
+ And we write a function which will step through our generator using ` next ` which in turn will utilize our
924
+ ` request ` method above to yield a Promise:
925
+
926
+ ``` javascript
927
+ function iterateGenerator (gen ) {
928
+ var generator = gen ();
929
+ var ret;
930
+ (function iterate (val ) {
931
+ ret = generator .next ();
932
+ if (! ret .done ) {
933
+ ret .value .then (iterate);
934
+ }
935
+ })();
936
+ }
937
+ ```
938
+
939
+ <sup >[ (回到目录)] ( #table-of-contents ) </sup >
940
+
941
+ By augmenting our Generator with Promises, we have a clear way of propogating errors through the use of our
942
+ Promise ` .catch ` and ` reject ` . To use our newly augmented Generator, it is as simple as before:
943
+
944
+ ``` javascript
945
+ iterateGenerator (function * getData () {
946
+ var entry1 = yield request (' http://some_api/item1' );
947
+ var data1 = JSON .parse (entry1);
948
+ var entry2 = yield request (' http://some_api/item2' );
949
+ var data2 = JSON .parse (entry2);
950
+ });
951
+ ```
952
+
953
+ We were able to reuse our implementation to use our Generator as before, which shows their power. While Generators
954
+ and Promises allow us to write asynchronous code in a synchronous manner while retaining the ability to propogate
955
+ errors in a nice way, we can actually begin to utilize a simpler construction that provides the same benefits:
956
+ [ async-await] ( https://github.com/DrkSephy/es6-cheatsheet#async-await ) .
957
+
958
+ <sup >[ (回到目录)] ( #table-of-contents ) </sup >
959
+
960
+ ## Async Await
961
+
962
+ While this is actually an upcoming ES2016 feature, ` async await ` allows us to perform the same thing we accomplished
963
+ using Generators and Promises with less effort:
964
+
965
+ ``` javascript
966
+ var request = require (' request' );
967
+
968
+ function getJSON (url ) {
969
+ return new Promise (function (resolve , reject ) {
970
+ request (url, function (error , response , body ) {
971
+ resolve (body);
972
+ });
973
+ });
974
+ }
975
+
976
+ async function main () {
977
+ var data = await getJSON ();
978
+ console .log (data); // NOT undefined!
979
+ }
980
+
981
+ main ();
982
+ ```
983
+
984
+ Under the hood, it performs similarly to Generators. I highly recommend using them over Generators + Promises. A great resource
985
+ for getting up and running with ES7 and Babel can be found [ here] ( http://masnun.com/2015/11/11/using-es7-asyncawait-today-with-babel.html ) .
986
+
987
+ <sup >[ (回到目录)] ( #table-of-contents ) </sup >
0 commit comments