Sharing Symbols

You may find that you want different parts of your code to use the same symbols. For example, suppose you have two different object types in your application that should use the same symbol property to represent a unique identifier. Keeping track of symbols across files or large codebases can be difficult and error-prone. That’s why ECMAScript 6 provides a global symbol registry that you can access at any point in time.

When you want to create a symbol to be shared, use the Symbol.for() method instead of calling the Symbol() method. The Symbol.for() method accepts a single parameter, which is a string identifier for the symbol you want to create. That parameter is also used as the symbol’s description. For example:

  1. let uid = Symbol.for("uid");
  2. let object = {};
  3. object[uid] = "12345";
  4. console.log(object[uid]); // "12345"
  5. console.log(uid); // "Symbol(uid)"

The Symbol.for() method first searches the global symbol registry to see if a symbol with the key "uid" exists. If so, the method returns the existing symbol. If no such symbol exists, then a new symbol is created and registered to the global symbol registry using the specified key. The new symbol is then returned. That means subsequent calls to Symbol.for() using the same key will return the same symbol, as follows:

  1. let uid = Symbol.for("uid");
  2. let object = {
  3. [uid]: "12345"
  4. };
  5. console.log(object[uid]); // "12345"
  6. console.log(uid); // "Symbol(uid)"
  7. let uid2 = Symbol.for("uid");
  8. console.log(uid === uid2); // true
  9. console.log(object[uid2]); // "12345"
  10. console.log(uid2); // "Symbol(uid)"

In this example, uid and uid2 contain the same symbol and so they can be used interchangeably. The first call to Symbol.for() creates the symbol, and the second call retrieves the symbol from the global symbol registry.

Another unique aspect of shared symbols is that you can retrieve the key associated with a symbol in the global symbol registry by calling the Symbol.keyFor() method. For example:

  1. let uid = Symbol.for("uid");
  2. console.log(Symbol.keyFor(uid)); // "uid"
  3. let uid2 = Symbol.for("uid");
  4. console.log(Symbol.keyFor(uid2)); // "uid"
  5. let uid3 = Symbol("uid");
  6. console.log(Symbol.keyFor(uid3)); // undefined

Notice that both uid and uid2 return the "uid" key. The symbol uid3 doesn’t exist in the global symbol registry, so it has no key associated with it and Symbol.keyFor() returns undefined.

W> The global symbol registry is a shared environment, just like the global scope. That means you can’t make assumptions about what is or is not already present in that environment. Use namespacing of symbol keys to reduce the likelihood of naming collisions when using third-party components. For example, jQuery code might use "jquery." to prefix all keys, for keys like "jquery.element" or similar.