Hello

@clarkpan

ansarada

ES6 symbols

what they are and how to use them

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
          

Whats actually happening

Symbols

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"
}
          

Use cases

No risk of collision


var isOpen = Symbol('isOpen');
var elm = document.getElementById('dropdown');

elm[isOpen] = true;
          

Built in Symbols


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
          

Hard to debug

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];
  }
}
          

Debug easily

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

Links

Thank you

@clarkpan

ansarada