Symbol is a new immutable primitive data type in JavaScript ES6.
Creating Symbol
It can be created by calling Symbol() function:
let s = Symbol();
console.log(s.toString());
console.log(typeof s)
console.log(typeof s === 'symbol')
Symbol cannot be converted to strings implicitly like in alert() or console.log() :
let s = Symbol();
console.log(s)
Symbol can also be created by passing a description (description does not serve any real purpose other than to be used in debugging):
let s = Symbol("my symbol");
console.log(s.toString())
s = Symbol(10);
console.log(s.toString())
s = Symbol(new Date());
console.log(s.toString())
Symbols are unique
Two symbols can never be the same:
let s1 = Symbol("my symbol");
let s2 = Symbol("my symbol");
console.log(s1 === s2)
What is the use of Symbols?
Using Symbol as object property name
Symbol can be used as an identifier for object properties:
let id = Symbol();
let employee = {};
employee[id] = 10;
employee['name'] = 'Mike';
console.log(employee[id]);
console.log(employee); //id ignored
Symbol key/value is ignored when we print the object (like above example). It is also ignore in for-in loop:
let id = Symbol();
let employee = {};
employee[id] = 10;
employee['name'] = 'Mike';
for (let k in employee) {
console.log(k);
}
So Symbol identifier can be used for some hidden properties.
They are also ignored by JSON.stringify() :
let id = Symbol();
let employee = {};
employee[id] = 10;
employee['name'] = 'Mike';
let json = JSON.stringify(employee);
console.log(json);
When Symbol is used as a key in object literal then we need to use square brackets (also see ES6 object literal changes):
let id = Symbol();
let employee = {
[id]: 10, name: 'Mike' };
console.log(employee);
Using Symbol as method/function name
Symbol can also be used as the name of a method:
let compare = Symbol();
class Math {
constructor() {
this.desc = "math utility";
}
//a method
[compare](x, y) {
return x === y ? 0 : x < y ? -1 : 1;
}
}
let math = new Math();
console.log(math);
let doCompare = math[compare];
let result = doCompare(7, 5);
console.log(result);
Using symbol method name in Object literal syntax:
let compare = Symbol();
let math = {
desc: 'math utility',
[compare](x, y) { return x === y ? 0 : x < y ? -1 : 1; } //using ES6 shorthand method syntax
};
console.log(math);
let result = math[compare](5, 7);
console.log(result);
let compare = Symbol();
let math = {
desc: "math utility",
[compare]: function(x, y) { return x === y ? 0 : x < y ? -1 : 1; } //using function syntax
};
console.log(math);
let result = math[compare](5, 7);
console.log(result);
Sharing symbols via a global registry
Symbols can also be created by using function Symbol.for(key) . In this case they are kept in a global symbol registry. For a given key if symbol already exits it is returned otherwise a new one is created, stored in the registry and returned:
let s1 = Symbol.for("test"); // new symbol created, stored with key 'test' and returned
let s2 = Symbol.for("test"); // as symbol with key 'test' already exits it is returned
console.log(s1 == s2);
Symbols created this way are available through out the application, even across different files.
Another method Symbol.keyFor(symbolInstance) can be used to get the Symbol's key:
let s = Symbol.for("test"); //global
let k = Symbol.keyFor(s);
console.log(k);
let s2 = Symbol("myDesc"); //not global
let k2 = Symbol.keyFor(s2);
console.log(k2);
Built-in symbol
JavaScript uses various built-in symbols internally which are also available to the developers since ES6.
|