@@ -662,22 +662,70 @@ beginners and allows us to write cleaner code.
662
662
## Symbols
663
663
664
664
Symbols have existed prior to ES6, but now we have a public interface to using
665
- them directly. One such example is to create unique property keys which will
666
- never collide:
665
+ them directly. Symbols are immutable and unique and can be used as keys in any hash.
667
666
668
- ``` javascript
669
- const key = Symbol ();
670
- const keyTwo = Symbol ();
671
- const object = {};
667
+ ### Symbol()
668
+
669
+ Calling ` Symbol() ` or ` Symbol(description) ` will create a unique symbol that cannot be looked up
670
+ globally. A Use case for ` Symbol() ` is to patch objects or namespaces from third parties with your own
671
+ logic, but be confident that you won't collide with updates to that library. For example,
672
+ if you wanted to add a method ` refreshComponent ` to the ` React.Component ` class, and be certain that
673
+ you didn't trample a method they add in a later update:
672
674
673
- object[key] = ' Such magic. ' ;
674
- object[keyTwo] = ' Much Uniqueness ' ;
675
+ ``` js
676
+ const refreshComponent = Symbol () ;
675
677
676
- // Two Symbols will never have the same value
677
- >> key === keyTwo
678
- >> false
678
+ React . Component . prototype [refreshComponent] = () => {
679
+ // do something
680
+ }
679
681
```
680
682
683
+
684
+ ### Symbol.for(key)
685
+
686
+ ` Symbol.for(key) ` will create a Symbol that is still immutable and unique, but can be looked up globally.
687
+ Two identical calls to ` Symbol.for(key) ` will return the same Symbol instance. NOTE: This is not true for ` Symbol(description) ` .
688
+
689
+ ``` js
690
+ Symbol (' foo' ) === Symbol (' foo' ) // false
691
+ Symbol .for (' foo' ) === Symbol (' foo' ) // false
692
+ Symbol .for (' foo' ) === Symbol .for (' foo' ) // true
693
+ ```
694
+
695
+ A common use case for Symbols, and in particular with ` Symbol.for(key) ` is for interoperability. This can be acheived by
696
+ having your code look for a Symbol member on object arguments from third parties that contain some known interface.
697
+ For example:
698
+
699
+ ``` js
700
+ function reader (obj ) {
701
+ const specialRead = Symbol .for (' specialRead' );
702
+ if (obj[specialRead]) {
703
+ const reader = obj[specialRead]();
704
+ // do something with reader
705
+ } else {
706
+ throw new TypeError (' object cannot be read' );
707
+ }
708
+ }
709
+ ```
710
+
711
+ and then in another library:
712
+
713
+ ``` js
714
+ const specialRead = Symbol .for (' specialRead' );
715
+
716
+ class SomeReadableType {
717
+ [specialRead ]() {
718
+ const reader = createSomeReaderFrom (this );
719
+ return reader;
720
+ }
721
+ }
722
+ ```
723
+
724
+ A notable example of Symbol use for interop is ` Symbol.iterable ` which exists on all iterable and iterator
725
+ types in ES6: Arrays, strings, generators, etc. When called as a method it returns an object with an Iterator
726
+ interface.
727
+
728
+
681
729
<sup >[ (back to table of contents)] ( #table-of-contents ) </sup >
682
730
683
731
## Maps
0 commit comments