Hello



Hello

0 0


Symbols_WDYK


On Github clark-pan / Symbols_WDYK

Hello

@clarkpan

ansarada

  • Encourage everyone to write modern javascript

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

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