bjects in Javascript are a widely used datatype for quick data storage and retrieval. The problem with objects is that there is no way to make a few properties private or exclude them from the iteration unless explicitly requested for those properties.
For example, you have a user object and want to print all the details inside the object except the password. The only way to exclude is to add an explicit condition to your loop while iterating over the object. Just imagine how messy your code will be if you do the same for multiple properties.
Luckily, Javascript introduced a new type, “Symbols,” in ES6, which will solve our problem.
Let’s dive deep into:
- What is a Symbol?
- What are the use cases of Symbols?
- How to use Symbols to resolve our problem with objects?
- Finally, Some tips on how to use symbols to code more efficiently.
Introduction
Symbols are a new primitive datatype introduced in Javascript. Symbols represent unique and immutable identifiers despite having the same name/description. This uniqueness made Symbols the best choice for keys or identifiers in Objects.
Symbols are particularly useful because they don’t show up during typical object property iteration methods, such as for…in loops or Object.keys(). This characteristic allows us to create properties within objects that remain hidden from most access methods.
How to create Symbols?
Symbols can be created by calling Symbol(). To simplify debugging, it also accepts an optional parameter, description.
const sym1 = Symbol();
const sym2 = Symbol();
console.log(sym1 === sym2); // false (guaranteed unique)const symWithDesc = Symbol("Simplified Ninja");
console.log(symWithDesc.description); // "Simplified Ninja"
Using Symbol as property key in Objects,
const passwordSymbol = Symbol("password");
const user = {
name: "Vamsi",
email: "sample@gmail.com",
password: "user@1234", // This should be private
[passwordSymbol]: "secret123"
};console.log(user.name); // "Vamsi" (accessible)
console.log(user.email); // "sample@gmail.com" (accessible)
console.log(user.password); // "user@1234" (accessible)
console.log(user[passwordSymbol]); // "secret123"// Looping doesn't reveal the symbol property
for (const key in user) {
console.log(key); // only prints "name", "email" and password but not the value with symbol
}
In this example, passwordSymbol is a private key for the password property. The password remains hidden since symbols are not included in typical object iteration.
Use cases of Symbols:
- Creating Private-like Properties and methods: As demonstrated above, symbols can be used to hide sensitive data within objects and classes.
- Preventing Property Name Collisions: Symbols generate unique references, hence avoiding any chances of duplicate properties.
Resolving Object Privacy Issue:
Symbols allow us to create a form of data privacy by hiding properties behind symbol keys. To print all user details except the password, all we need to do is define the property as Symbol:
const passwordSymbol = Symbol("password");
const user = {
name: "Vamsi",
email: "sample@gmail.com",
password: "user@1234", // This should be private
[passwordSymbol]: "secret123"
};for (const key in user) {
console.log(key, user[key]);
// Object keys with symbols, do not even enter into the loop.,
}
Tips for Using Symbols Effectively
- Use symbols for truly sensitive data: Symbols offer a layer of protection, but determined attackers can potentially access private data through more advanced techniques.
- Document symbol usage: Since symbols aren’t readily apparent in code, clearly document their purpose to improve code readability and maintainability.
- Consider alternative approaches: Depending on your specific needs, alternative approaches like closures or WeakMaps might be more suitable for certain privacy scenarios.