ES6 Symbols


Published: 2017-11-26
Updated: 2017-12-26
Web: http://fritzthecat-blog.blogspot.com/2017/11/es6-symbols.html


ES6: ?

Before ES6, JavaScript had following data-types:

  1. Undefined
  2. Null
  3. Boolean
  4. Number
  5. String
  6. Object

Now, with ES6, we have a new data-type:

A Symbol is neither String nor Object nor Number. The Symbol() function can be regarded as an id-generator. A symbol instance is an unique identity.

Purpose

Symbols should be used as an alternative to property names. Properties are always public, and thus vulnerable. If you store something into a DOM-node as a named property, some other library may have chosen the same property name, and may overwrite your value. This is not possible if you use a symbol as key, instead of a string, because symbols are unique and runtime-generated.

const displayed = Symbol()
// ....

domNode[displayed] = true
// ....

if (domNode[displayed])
    decorate(domNode)

Such symbol-properties are not private, but at least they are a way to separate concerns, and get away from all those dubious string property bindings.

The only atrocity is that you always need to use the square-bracket notation myObject[mySymbol]. The conventional dot notation myObject.mySymbol does not work!

Also be aware that symbol-properties don't get serialized (→ transient), so they won't arrive on the server when their wrapping object was sent by AJAX.

ES6 Symbol Tests

Work through examples below to get familiar with symbols. Click onto one of the buttons to get example source code into the text field. In the area below it you can find explanations about the example.

Description

Resume

String bindings make all programming languages vulnerable, even compiled ones. Unexperienced programmers often stick to such notations, because they think it makes the code understandable. Yes, may be true, but it is also dangerous. You can not control thousands of lines of code just by understanding them. You need encapsulation mechanisms. ES6 symbols are a very welcome alternative to string-properties.




A Symbol() call is like retrieving a value from a database-sequence. You always get a new value that was not yet used. You could also call that "id-generator".

The optional parameter to Symbol() is just for debugging purposes. It does not influence the generated symbol in any way.

It is possible to put values into objects using symbols as key in square brackets. Take care to remember the symbol somewhere, else you will not be able to retrieve the value any more.

It is not possible to access symbol-properties using the dot-notation. This does not throw an exception, but you will get back undefined.

You can not construct symbols using new Symbol(). This throws an exception.

Symbols can not be stringified. When used in string-concatenation, an exception will be thrown. This will be quite demanding for console.log() debug outputs ....

Symbols in objects can be found out by by Object.getOwnPropertySymbols(). You get back an array of all symbols that have been defined on the given object. But the Object.getOwnPropertyNames() function and the for-in loop do not find symbols.

Symbols do not get not serialized like properties.

You can create global symbols using Symbol.for() and Symbol.keyFor() functions. That way you can bind a symbol to a string identifier. After creation, the symbol is immutable, like a constant. This can also be useful as enumerations.

This is the way how you can convert a symbol to a string.
See also "Nature of Symbols, Part 2" about the problems with converting symbols to string.


ɔ⃝ Fritz Ritzberger, 2017-11-26