ES6/ES2015 For Newbies Lesson 6: Symbols

Share:
Source Code

A symbol is a unique and immutable data type and may be used as an identifier for object properties. The Symbol object is an implicit object wrapper for the symbol primitive data type.

 

In plain english, Symbol is:

  • New primitive in ES6
  • Unique and immutable data type
  • Introduces concept of namespace

Uniqueness

Let’s take a look at the following:

const COLOR_BLUE = 'blue';
const COLOR_BAD_BLUE = 'blue';
console.log(COLOR_BLUE === COLOR_BAD_BLUE);

Here, the two variables are actually equal to each other when the value they’re being set to are the same.

Symbols are different, they’re totally unique and are guaranteed to be that way:

const COLOR_RED = Symbol('red');
const COLOR_BAD_RED = Symbol('red');
console.log(COLOR_RED === COLOR_BAD_RED);

even though both variables are initialized to be the same Symbol, they’re not actually equal.  You can think of what Symbol does under the hood as a random value generator, it generates a value that’s truly unique within the namespace they’re confined in (a namespace is an execute context the code is running in, such as inside of an iframe).

Value retrieval

Symbols cannot be converted to a String:

// They cannot be coverted to string implicitly
const foo = Symbol('foo');
const sentence = 'My favorite word is ' + foo;
console.log(anotherSentence);

This will generate an error on the interpreter, because Symbol is not and cannot be turned into a string.

You can however, do this:

const anotherSentence = 'hello ' + String(foo);

but the output will be the string hello Symbol(foo) , literately.

Enumeration

Let’s use Symbols to set an object’s key property:

// A word about enumerating Symbols
const myObj = {
	[Symbol('name')]: 'sally',
	property1: 1,
	property2: 2
};

this is very useful for when you want to update an existing code base, but is afraid that you might occidentally override something someone might’ve set already.

If we want to enumerate through the properties of myObj, I can do it the following ways:

To get a list of keys that do not include symbols:

console.log(Object.keys(myObj));

To get only symbol properties:

console.log(Object.getOwnPropertySymbols(myObj));

To get everything from the object:

console.log(Reflect.ownKeys(myObj));

To lookup a certain Symbol with key name:

console.log(Symbol.for('x') === Symbol.for('x'))

^ Here, if Symbol.for(‘x’) does not exist, the first call will create it, by the time it get to the comparison on the right hand side, it’s used as a lookup, so Symbol.for() both creates and looks up a symbol.

Symbols also serve an important function in iterators (Symbol.iterator), which we will look at in the next lesson.

To recap, What do we use Symbols for?

  1. To define unique object properties to avoid name clashes
  2. “Private” property, you can only access them via ES6 apis, meaning you’ll have to explicitly ask for them, serves as a protection against accidental access
  3. Predefined way to define implementation, example Symbol.iterator

[frames playlist=’3′]

Comments Or Questions? Discuss In Our Discord

If you enjoyed this tutorial, make sure to subscribe to our Youtube Channel and follow us on Twitter @pentacodevids for latest updates!

More from PentaCode