Symbol Type
Objects the Basics: Symbol Type
What are the two types of object property keys in JavaScript?
View Answer:
Interview Response: By specification, object property keys may be a string or symbol type. These two types are not numbers, not Booleans, only strings or symbols.
Explain what a Symbol is in JavaScript?
View Answer:
Interview Response: The data type symbol is a primitive data type. The Symbol() object returns a value of type symbol, and it has static properties that expose several members of built-in objects. It also has static methods that expose the global symbol registry and resembles a built-in object class. A "symbol" represents a unique identifier.
Code Example:
let sym1 = Symbol();
let sym2 = Symbol('foo');
let sym3 = Symbol('foo');
Symbol('foo') === Symbol('foo'); // false, Symbol returns a unique
Does the Symbol function get registered in the global symbol registry?
View Answer:
Interview Response: No, the Symbol object does not create a global symbol available in your whole codebase. To create symbols available across files and even across realms (each of which has its global scope), use the methods Symbol.for() and Symbol.keyFor() to set and retrieve symbols from the global symbol registry.
Can two Symbol descriptions be identical in JavaScript?
View Answer:
Interview Response: The description can be identical, but the value is unique and returns false if both values get compared.
Code Example:
let id1 = Symbol('id');
let id2 = Symbol('id');
alert(id1 == id2); // false
Do Symbols auto-convert to strings in JavaScript?
View Answer:
Interview Response: Most values in JavaScript support implicit conversion to a string, but a symbol is rare and unique, and it does not auto-convert to a string. This behavior is an intentional "language guard" against messing up because strings and symbols are fundamentally different and should not accidentally convert one into another.
Code Example:
let id = Symbol('id');
alert(id); // TypeError: Cannot convert a Symbol value to a string
// Solution
let id = Symbol('id');
alert(id.toString()); // Symbol(id), now it works
To explicitly convert a Symbol to a string, what built-in method should we use?
View Answer:
Interview Response: We should explicitly call the toString() method to convert a Symbol to a string.
Code Example:
let id = Symbol('id');
alert(id.toString()); // Symbol(id), now it works
If you want to show the Symbol description, what property should you use?
View Answer:
Interview Response: To get and show a symbol description, we should use the description property and dot notation to access the value.
Code Example:
let id = Symbol('id');
alert(id.description); // returns id
How can the Symbol object act as a property safeguard in objects?
View Answer:
Interview Response: Symbols can create hidden object properties that cannot be overwritten or accidentally accessed. Unique properties like ids can conflict with ids from external libraries. A Symbol can act as a hidden property and reduce the likelihood of property conflicts and bugs in our application.
Code Example:
let user = {
// belongs to another code
name: 'John',
};
let id = Symbol('id');
user[id] = 1;
alert(user[id]);
// returns 1, in user[id], we can access the data using the symbol as the key
What is the benefit of using Symbol("id") over a string "id"?
View Answer:
Interview Response: Symbols allow us to create secured properties of an object so that no other part of code can accidentally accessed or overwritten. If a user object, for example, belongs to another codebase, and that code also works with the same user properties, we shouldn’t just add any fields to it, and that’s unsafe. If we use a Symbol(), the external library cannot accidentally access its property. In fact, the third-party library probably won’t even see it, so it’s probably all right to do. The benefit is a cloak created by Symbol to reduce object property conflicts.
Code Example:
// ...
let id = Symbol('id');
user[id] = 'Their id value';
Code Example: Conflicting Properties
let user = { name: 'John' };
// Our script uses "id" property
user.id = 'Our id value';
// ...Another script also wants "id" for its purposes...
user.id = 'Their id value';
// Boom! overwritten by another script!
Can you use a Symbol in an object literal?
View Answer:
Interview Response: Yes, we can achieve this by wrapping the property in square brackets. This approach allows the property to be a key and not a string.
Code Example:
let id = Symbol('id');
let user = {
name: 'John',
[id]: 123, // not "id": 123
};
Can you return a Symbol in a for…in loop?
View Answer:
Interview Response: No, you can access it directly, but for…in loop does not return the property. That is a part of the safeguarding of symbolic properties in principle. If another script or a library loops over our object, it will not unexpectedly access a symbolic property.
Code Example:
let id = Symbol('id');
let user = {
name: 'John',
age: 30,
[id]: 123,
};
for (let key in user) alert(key); // name, age (no symbols)
// the direct access by the symbol works
alert('Direct: ' + user[id]);
JavaScript hides Symbol properties for a reason. Is there a way to copy all the properties, including the symbolic ones?
View Answer:
Interview Response: Yes, symbolic properties can be cloned in an object by using object.assign to copy both the string and symbol properties. This behavior ensures that all the properties, strings, and symbols, are copied into the newly cloned object.
Code Example:
let id = Symbol('id');
let user = {
[id]: 123,
};
let clone = Object.assign({}, user);
alert(clone[id]); // 123
Sometimes, you need to have the same-named symbols to be the same entities. Is there a way to read or create a symbol from the registry?
View Answer:
Interview Response: Yes, we can use the Symbol.for(key) to check the global registry and return it if available. Otherwise, it creates a new symbol Symbol(key) and stores it in the global registry by the given key. Symbols inside the registry are called global symbols.
Code Example:
// read from the global registry
let id = Symbol.for('id'); // if the symbol did not exist, it is created
// read it again (maybe from another part of the code)
let idAgain = Symbol.for('id');
// the same symbol
alert(id === idAgain); // true
What is the difference between Symbol.for(key) and Symbol.keyFor(sym) in JavaScript?
View Answer:
Interview Response: Symbol.for(key) returns a symbol by name, and Symbol.keyFor(sym) returns a name by a global symbol.
Code Example:
// get symbol by name
let sym = Symbol.for('name');
let sym2 = Symbol.for('id');
// get name by symbol
alert(Symbol.keyFor(sym)); // name
alert(Symbol.keyFor(sym2)); // id
The Symbol.keyFor internally uses the global symbol registry to look up the key for the symbol. Does it work for non-global symbols?
View Answer:
Interview Response: No, local or non-global symbols do not get placed in the global symbol registry.
Technical Response: Symbol.for(key) returns a symbol by name, and Symbol.keyFor(sym) returns a name by a global symbol. If the symbol is not global, it does not find it and returns undefined. Notably, we must remember that all symbols, including non-global symbols, can return a description.
Code Example:
let globalSymbol = Symbol.for('name');
let localSymbol = Symbol('name');
alert(Symbol.keyFor(globalSymbol)); // name, global symbol
alert(Symbol.keyFor(localSymbol)); // undefined, not global
alert(localSymbol.description); // name