ES6 symbols
what they are and how to use them
- ES6 coming around the corner
- Should learn new language features today
Property Access
var person = {};
person.name = "Clark";
console.log(person.name); // Clark
console.log(person['name']); // Clark
var key = 'name';
console.log(person[key]); // Clark
Using an object as a key
var weight = { type: "weight" };
person[weight] = 84;
console.log(person[weight]); // 84
Using a second object as a key
var height = { type: "height" };
person[height] = 180;
console.log(person[height]); // 180
But wait...
console.log(person[weight]); // 180
Basic usage
var nameSymbol = Symbol();
var person = {};
person[nameSymbol] = "Clark";
console.log(person[nameSymbol]); // Clark
Optional name parameter
var nameSymbol = Symbol("name");
Symbols are unique
console.log(Symbol("name") == Symbol("name")); // false
A new primitive
console.log(typeof nameSymbol); // symbol
nameSymbol.foo = "Foo";
console.log(nameSymbol.foo); // undefined
Protects access to values
var age = Symbol("age");
var person = {
"name" : "Clark",
[age] : 28
};
console.log(person.age); // undefined
console.log(person[age]); // 28
for(var key in person){
console.log(person[key]); // Would only log "Clark"
}
No risk of collision
var isOpen = Symbol('isOpen');
var elm = document.getElementById('dropdown');
elm[isOpen] = true;
var things = [1, 'apple', 2, 'banana', 3, 'pear'],
thing;
for(thing of things){
console.log(thing);
}
// Output:
// 1
// apple
// 2
// banana
// 3
// pear
Symbol.iterator
things[Symbol.iterator] = function*(){
for(let i = 0; i < this.length; i++){
if(typeof this[i] === "string") yield this[i];
}
}
for(thing of things){
console.log(thing);
}
// Output:
// apple
// banana
// pear
Encapsulation without (ab)using closures
Hiding variables using closures
function Television(){
var hasPower = false;
this.powerButton = function(){
if(hasPower){
console.log("TV switched off");
} else {
console.log("TV switched on");
}
hasPower = !hasPower;
}
}
var tv = new Television();
tv.powerButton(); // TV switched on
Bad for code reuse
function PlasmaTV(){
//Cannot access hasPower
console.log(this.hasPower); //undefined
}
PlasmaTV.prototype = new Television();
Closures have a performance penalty
function Television(){
var hasPower = false;
this.powerButton = function(){
if(hasPower){
console.log("TV switched off");
} else {
console.log("TV switched on");
}
hasPower = !hasPower;
}
}
Encapsulation with symbols
Hiding variables using symbols
const hasPowerKey = Symbol('hasPower');
class Television {
constructor() {
this[hasPowerKey] = false;
}
powerButton() {
if(this[hasPowerKey]){
console.log("TV switched off");
} else {
console.log("TV switched on");
}
this[hasPowerKey] = !this[hasPowerKey];
}
}
Code reuse
function PlasmaTV(){
Television.apply(this);
console.log(this[hasPowerKey]); //false
}
PlasmaTV.prototype = new Television();
Functions only created once
const hasPowerKey = Symbol('hasPower');
class Television {
constructor() {
this[hasPowerKey] = false;
}
powerButton() {
if(this[hasPowerKey]){
console.log("TV switched off");
} else {
console.log("TV switched on");
}
this[hasPowerKey] = !this[hasPowerKey];
}
}
Browser support
- Chrome, Firefox, Opera, IE Edge ✓
- Safari, not yet but Symbols is in webkit
- NodeJS behind the --harmony flag
- IO.js without any flags
Symbols
- New language primitive Symbols
- Used for some new built-in language features
- Very useful for organising your own code