Basics of JavaScript Symbols






4.94/5 (8 votes)
An introduction to JavaScript Symbol type
Introduction
Symbols are the newest JavaScript primitive as of this writing. In fact, many developers aren’t aware that this feature exists, including me at first. Bringing in a new feature to a language means benefits to the language and we should understand the particular use of a certain feature. Therefore, we are going to tackle the benefits and its particular usage of JavaScript symbols. OK, then let’s get started.
Table of Contents
- What is JavaScript Symbol?
- Benefits and Usage of JavaScript Symbol
- Creating a new JavaScript Symbol is always unique
- JavaScript Symbol with description, mainly used for debugging
- JavaScript Symbol with the same description isn't equal
- Symbol() function when invoking a new instance
- JavaScript Symbol type and conversion to a string
- Use JavaScript Symbol as object keys
- The Symbol.for method
- Preventing Property-name Collisions
- Summary
- History
What is JavaScript Symbol?
JavaScript Symbol is a new primitive type introduced in ES6. In addition, a symbol is a unique and immutable value. Creating a new symbol is quite easy, you just need to call the Symbol()
function which returns a unique symbol every time it is invoked. Will get into examples in later sections.
Benefits and Usage of JavaScript Symbol?
Creating a new JavaScript Symbol is always unique
As we have described in the previous section, we said that in order to create a new JavaScript symbol, we just need to call the Symbol
function. Another thing to mention about it, symbols don’t have literal form; thus, we can only use the Symbol()
function to create one.
See the example below.
//how to create a Symbol
const mySymbol1 = Symbol();
const mySymbol2 = Symbol();
console.log(mySymbol1, mySymbol2);
//output: Symbol() Symbol()
JavaScript Symbol with description, mainly used for debugging
Now, that we have seen how to create a new JavaScript Symbol. Let’s not forget that, a Symbol()
function takes an optional string parameter which represents that description of the Symbol
. Based on my experience, the description is used for debugging purposes but not to access the Symbol
itself.
See the example below:
//* how to create a Symbol with description
const mySymbolWithDescription1 = Symbol("First description");
const mySymbolWithDescription2 = Symbol("Second description");
console.log(mySymbolWithDescription1, mySymbolWithDescription2);
//output: Symbol(First description) Symbol(Second description)
JavaScript Symbol with the same description isn't equal
Symbols are always 100% guaranteed to be unique. Remember, that description is just a label
that doesn't affect anything. Again, the description is just a label
nothing more nothing less.
See the example below:
//Symbol with same description aren't equal
const mySymbol_1 = Symbol("Cat");
const mySymbol_2 = Symbol("Cat");
console.dir(mySymbol_1 === mySymbol_2);
//output: false
Symbol() function when invoking a new instance
The first time I learned JavaScript Symbol, I thought I can create a new instance by using the Symbol()
function. Eventually, it throws an error that says: “Symbol is not a constructor”
when creating a new instance.
See the example below:
//how not to create a Symbol
try {
const _newSymbols = new Symbol();
} catch (error) {
console.dir(error.message); //output: Symbol is not a constructor
}
So, as you can see in the example above, using a new keyword to create a new instance of the Symbol
isn't going to work because based on our previous section, we have to directly invoke the Symbol()
function.
JavaScript Symbol type and conversion to a string
It's always been fun to use the typeof
operator. Thus, the result would be a symbol
and not an object because it is primitive.
Based on my observation, JavaScript types support implicit conversion to string
. However, Symbol
type doesn't auto-convert. You really need to explicitly call the .toString()
method.
Check type using the typeof operator
//Let's check if the type name of Symbol
const mySymbolType = Symbol();
console.log(typeof mySymbolType);
//output: symbol
Call the type Symbol inside the alert function
const mySymbolType = Symbol();
alert(mySymbolType);
//output: Uncaught TypeError: Cannot convert a Symbol value to a string
Explicit usage of .toString() and use of description property
const _newSymbols2 = Symbol("Hello");
console.log(_newSymbols2.toString()); //output: Symbol(Hello)
console.log(_newSymbols2.description); //output: Hello
Use JavaScript Symbol as object keys
As of today, the JavaScript object property keys can be strings or symbols. Moreover, an object having a Symbol
type of property will not be listed when you try to enumerate the object keys. Thus, in my opinion, it looks hidden when you enumerate but not exactly when you use the []token.
See the examples below:
const customerSymbol = Symbol("Object date created");
let customer = {
name: "Jin Vincent Necesario",
[customerSymbol]: new Date()
};
console.log(customer);
Output:
Let's try to enumerate by using the for-in loop
for (const key in customer) {
if (customer.hasOwnProperty(key)) {
console.log(`customer.${key} is equals to ${customer[key]}`);
}
}
//output: customer.name is equals to Jin Vincent Necesario
//Note: The symbol-key didn't appear to be part of the object
Directly Access the Symbol Property
However, we can access that contains the symbol via []
token.
console.log("customer[customerSymbol] is equals to " + customer[customerSymbol].getFullYear());
//output: customer[customerSymbol] is equals to 2020
But, of course, there's another way to access the Symbols directly by the use of Object.getOwnPropertySymbols()
method.
console.log(Object.getOwnPropertySymbols(customer));
Output:
The Symbol.for Method
Basically, the Symbol
object maintains a registry of the key/value, where the key is the description, and the value is the symbol. Now, when using a Symbol.for
method, it gets added to the registry and the method returns the symbol. Thus, if we try to create a symbol with an existing description, then it will be retrieved.
//create a symbol using for method
const mySymbolFor = Symbol.for("My Unique Description");
let product = {
name: "Toyota",
[mySymbolFor]: "Toyota Hilux G"
};
const mySymbolFor2 = Symbol.for("My Unique Description");
console.log(mySymbolFor === mySymbolFor2); //output:true
Preventing Property-name Collisions
Now, you have gone this far. You might actually be getting your hands dirty with JavaScript Symbol. And, you might be asking: "What's the benefit?".
Actually, they are useful in situations where libraries want to add properties to objects without the risk of having the name collisions.
Summary
- Symbols are invoked with the use of
Symbol()
function when you try to use a new instance an error will be thrown. - JavaScript Symbols are always unique.
- Symbols descriptions are purposely for debugging and having the same description doesn't mean Symbols are equivalent.
- JavaScript Symbols should be explicitly converted into a
string
, if you wanted to. - JavaScript can be used within an object property to prevent property name collisions.
- The
Symbol.for
has a table registry for key-value pair, which retrieves existing symbol description, else creates a new one.
I hope you have enjoyed this article, as I have enjoyed writing it. Stay tuned for more. Until next time, happy programming!
History
- 31st July, 2020: Initial version