CHAPTER 13
Symbols are a new primitive type in ES6. Symbols are tokens that serve as unique IDs. You create symbols via the factory function Symbol().
Let’s take a look at an example using symbols:
Code Listing: 191
Symbol("foo") !== Symbol("foo") const foo = Symbol('test1'); const bar = Symbol('test2'); typeof foo === "symbol"; typeof bar === "symbol"; let obj = {}; obj[foo] = "foo"; obj[bar] = "bar"; console.log(JSON.stringify(obj)); console.log(Object.keys(obj)); console.log(Object.getOwnPropertyNames(obj)); console.log(Object.getOwnPropertySymbols(obj)); |
As you can see, symbols are unique and no two symbols will equal each other. Also note how we are assigning symbols to object properties. We use the symbol as the key for the object and assign a value to it. Also observe that you can pass a string into the constructor of a symbol, but it is used only for debugging purposes.
Let’s take a look at the output from the preceding code:
Code Listing: 192
{} [] [] [ Symbol(test1), Symbol(test2) ] |
Given that we now have a new kind of value that can become the key of a property, the following terminology is used for ES6:
The name of Object.keys() doesn’t really work. It only considers property keys that are strings. This explains why our output was only an empty array ([]).
Likewise, the name Object.getOwnPropertyName() only returns property keys that are strings as well.
If you want a symbol to be the same in all realms, you need to create it via the global symbol registry. Let’s look at the following example:
Code Listing: 193
Symbol.for("app.foo") === Symbol.for("app.foo") const foo = Symbol.for("app.foo") const bar = Symbol.for("app.bar") Symbol.keyFor(foo) === "app.foo" Symbol.keyFor(bar) === "app.bar" typeof foo === "symbol" typeof bar === "symbol" let obj = {} obj[foo] = "foo" obj[bar] = "bar" console.log(JSON.stringify(obj)); console.log(Object.keys(obj)); console.log(Object.getOwnPropertyNames(obj)); console.log(Object.getOwnPropertySymbols(obj)); |
Notice that we now have the Symbol.for function. This is how we place the symbol in the global registry. Also notice how we assign a key for a symbol using the Symbol.keyFor function.
Global symbols behave the same as normal symbols, as we can see from the output from the preceding code:
Code Listing: 194
{} [] [] [ Symbol(app.foo), Symbol(app.bar) ] |