JavaScript: Symbol (ES2015)

By Xah Lee. Date: . Last updated: .

Symbol is a new primitive type in JavaScript. 〔➤see JavaScript: Data Types

The Symbol type is the set of all non-string values that may be used as the key of a object property.

The purpose of symbol is to avoid property name collision.

Each possible symbol value is unique and immutable.

Each symbol value has an associated value called “Description”, usually denoted in document as [[Description]] that is either undefined or a value of string type. This [[Description]] cannot be changed.

Creating Symbol

var x = Symbol(); → creates a symbol.

var x = Symbol(description); → creates a symbol with description string description. The description is a printed representation of the symbol, mostly for debugging purposes. By default, the description is a string "undefined". The description is used when you convert symbol to string. Note: 2 symbols with same description are still different symbols.

// creating symbol

const x = Symbol();
const y = Symbol();
const z = Symbol("my cat");

console.log(x); // prints Symbol()
console.log(y); // prints Symbol()
console.log(z); // prints Symbol(my cat)

typeof on symbol value returns string "symbol".

// typeof on symbol

var x = Symbol();
console.log( typeof x === "symbol" ); // true

var y = Symbol("abc");
console.log( typeof y === "symbol" ); // true

〔➤see JavaScript: Data Types

「Symbol()」 Cannot be Used with 「new」

Symbol() cannot be used with new.

// Symbol() cannot be used as constructor
var x = new Symbol();
// TypeError: Symbol is not a constructor

Symbol() Returns a Unique Symbol, Always

// Symbol() always returns a unique symbol

var x = Symbol();
var y = Symbol();

console.log(x === y); // prints false

Using Symbol as Property Key

The symbol type is primarily designed to be keys for properties. Because symbol values are unique, this means property key collision cannot happen. Now you can add properties to objects in libraries or your own library and don't have to worry about property key collision.

Before ES2015, property key can only be string type. In ES2015, property key can be either a string type or symbol type.

Use bracket notation to access property symbol. For example, obj[variable_of_symbol] or obj[symbol_value].

// adding a property with symbol key, via a variable's value
var x = Symbol();
var obj = {};
obj[x] = 3;
console.log(obj[x]); // 3
// adding a property with symbol key, via symbol value directly
var obj = {};
obj[Symbol()] = 4;

console.log(
    obj[Object.getOwnPropertySymbols(obj)[0]]
) // 4

// getOwnPropertySymbols returns a array of symbol keys

Note: you cannot use dot notation for property keys that are symbol. 〔➤see JavaScript: Dot Notation vs Bracket Notation for Accessing Properties

Computed Property Key

ES2015 extended object literal expression syntax to allow dynamically evaluated property key. Like this:

var obj = {[expression]:value}

This is especially useful for symbol key.

// es2016 computed property syntax. use [] around the property key
var aa = Symbol();
var obj = {[aa]:3};   // symbol
console.log(obj[aa]); // 3

〔➤see JavaScript: Object Literal Expression Extensions (ES2015)

Symbol Properties Are Usually Ignored

Properties with symbol as key are usually ignored by constructs that access properties.

var x = Symbol();
var obj = {};
obj[x] = 4;

console.log(obj[x]); // 4, exists

// symbol key properties are ignored by many constructs
console.log(obj); // {}
console.log(Object.keys(obj)); // []
console.log(Object.getOwnPropertyNames(obj)); // []

for (var p in obj) { console.log(p); } // prints nothing

〔➤see JavaScript: Access/List Properties

Check If a Key Exist

Object.prototype.hasOwnProperty(key) works with symbol keys. (and string keys too)

// Object.prototype.hasOwnProperty works with symbol keys
var x = Symbol();
var u = {};
u[x] = 3;
console.log(u.hasOwnProperty ( x )); // true

Access Symbol Key Properties

If you have a variable that holds a symbol value, you can access it by bracket notation, like this: obj[var_of_symbol].

var x = Symbol("xyz");
var obj = {};
obj[x] = 4;

// bracket notation to access symbol property
console.log( obj[x] ); // 4

getOwnPropertySymbols

Object.getOwnPropertySymbols(obj) → return a array of symbol keys of obj.

// list symbol key properties of a object

var x = Symbol("xyz");
var obj = {};
obj[x] = 4;

console.log(
    Object.getOwnPropertySymbols(obj)
); // prints [ Symbol(xyz) ]

〔➤see JavaScript: Object Object and Properties

ES2015 §Fundamental Objects#sec-object.getownpropertysymbols

Reflect.ownKeys()

Reflect.ownKeys(obj) → return a array of all property keys, including string valued ones and symbol valued ones.

var obj = {};
obj["y"] = 3;
obj[Symbol("x")] = 4;

// list all properties of a object, string valued and symbol valued
console.log(
    Reflect.ownKeys(obj)
); // prints [ 'y', Symbol(x) ]

〔➤see JavaScript: Reflect Object and Properties (ES2015)

ES2015 §Reflection#sec-reflect.ownkeys

Object.assign()

Object.assign()

Convert Symbol to String

var s = Symbol("cat");

console.log("my " + s)
// TypeError: Cannot convert a Symbol value to a string
// convert symbol to string

var s = Symbol("cat");

console.log(s.toString()); // Symbol(cat)

// or
console.log(String(s)); // Symbol(cat)

2016-11-04 the following is work in progress

Symbol Registery

Symbol.for(string) → access shared symbols registry.

Symbol Function Object

Symbol() is a function object. It is a property of the global object. (in web browser, the global object is window. 〔➤see JavaScript: Browser Window Object, Document Object Model〕)

The parent (aka prototype) of Symbol is the object Symbol.prototype.

Symbol Function Object Properties

The function Symbol() is a function, thus a object. It has properties.

Symbol.for(key)

Symbol.hasInstance

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Symbol.isConcatSpreadable

The initial value of Symbol.isConcatSpreadable is the well known symbol @@isConcatSpreadable (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.iterator

The initial value of Symbol.iterator is the well known symbol @@iterator (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Symbol.match

The initial value of Symbol.match is the well known symbol @@match (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.prototype

The initial value of Symbol.prototype is the intrinsic object %SymbolPrototype% (19.4.3).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.replace

The initial value of Symbol.replace is the well known symbol @@replace (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.search

Symbol.species

The initial value of Symbol.species is the well known symbol @@species (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.split

The initial value of Symbol.split is the well known symbol @@split (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.toPrimitive

The initial value of Symbol.toPrimitive is the well known symbol @@toPrimitive (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.toStringTag

The initial value of Symbol.toStringTag is the well known symbol @@toStringTag (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }. Symbol.unscopables

The initial value of Symbol.unscopables is the well known symbol @@unscopables (Table 1).

This property has the attributes { [[Writable]]: false, [[Enumerable]]: false, [[Configurable]]: false }.

Well-Known (Predefined) Symbols

Well-Known symbols are symbols predefined by the js standard.

Well-known symbols are built-in Symbol values They are typically used as the keys of properties whose values serve as extension points. Unless otherwise specified, well-known symbols values are shared by all Code Realms.

Well-Known symbols are denoted with 2 at signs in front, like this: @@iterator

Symbol.iterator

the operator instanceof is now a method of function, with property key [Symbol.hasInstance]. someting like o instanceof f same as f[Symbol.hasInstance](o). this makes it extensible. todo

Symbol.unscopables

Symbol.match method for customizing str.match(obj). todo

Well-known Symbols
Specification Name [[Description]] Value and Purpose
@@hasInstance "Symbol.hasInstance" A method that determines if a constructor object recognizes an object as one of the constructor’s instances. Called by the semantics of the instanceof operator.
@@isConcatSpreadable "Symbol.isConcatSpreadable" A Boolean valued property that if true indicates that an object should be flattened to its array elements by Array.prototype.concat.
@@iterator "Symbol.iterator" A method that returns the default Iterator for an object. Called by the semantics of the for-of statement.
@@match "Symbol.match" A regular expression method that matches the regular expression against a string. Called by the String.prototype.match method.
@@replace "Symbol.replace" A regular expression method that replaces matched substrings of a string. Called by the String.prototype.replace method.
@@search "Symbol.search" A regular expression method that returns the index within a string that matches the regular expression. Called by the String.prototype.search method.
@@species "Symbol.species" A function valued property that is the constructor function that is used to create derived objects.
@@split "Symbol.split" A regular expression method that splits a string at the indices that match the regular expression. Called by the String.prototype.split method.
@@toPrimitive "Symbol.toPrimitive" A method that converts an object to a corresponding primitive value. Called by the ToPrimitive abstract operation.
@@toStringTag "Symbol.toStringTag" A String valued property that is used in the creation of the default string description of an object. Accessed by the built-in method Object.prototype.toString.
@@unscopables "Symbol.unscopables" An object valued property whose own property names are property names that are excluded from the with environment bindings of the associated object.

Reference

ES2015 §ECMAScript Data Types and Values#sec-ecmascript-language-types-symbol-type

ES2015 §Fundamental Objects#sec-symbol-objects

https://hacks.mozilla.org/2015/06/es6-in-depth-symbols/

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

http://www.2ality.com/2014/12/es6-symbols.html

Like what you read? Buy JavaScript in Depth
or, buy a new keyboard, see Keyboard Reviews.