Skip to content

Commit d8a45f2

Browse files
committed
Add additional information about Symbols
1 parent a5c486d commit d8a45f2

File tree

1 file changed

+59
-11
lines changed

1 file changed

+59
-11
lines changed

README.md

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -662,22 +662,70 @@ beginners and allows us to write cleaner code.
662662
## Symbols
663663

664664
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.
667666

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:
672674

673-
object[key] = 'Such magic.';
674-
object[keyTwo] = 'Much Uniqueness';
675+
```js
676+
const refreshComponent = Symbol();
675677

676-
// Two Symbols will never have the same value
677-
>> key === keyTwo
678-
>> false
678+
React.Component.prototype[refreshComponent] = () => {
679+
// do something
680+
}
679681
```
680682

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+
681729
<sup>[(back to table of contents)](#table-of-contents)</sup>
682730

683731
## Maps

0 commit comments

Comments
 (0)