Hacking with ES6
by @chambaz
Feat. Harry Kane

Disclaimer
I am not an expert.

History

A brief history of JavaScript...
- 1995 LiveScript released and later renamed to JavaScript
- 1997 ECMAScript 1 (ES1) officially released
- 1999 saw big improvements with ES3
- DRAMA! ES4 abandoned
- 2009 TC39 resolves differences and ES5 released
- 2014 ES6 frozen
- Now called JS2015 (smh)
Why Now?

I can haz ES6?!...
- Browsers are starting to implement ES6 features
- Firefox is the furthest along followed by Chrome
- Transpilers, Babel, Traceur
- Preparing for the future and Angular 2.0
No.
It's all about preparation...
Features
Short hand Objects
Object literal properties
var obj = {
// old way
doSomething: function() {
},
// new way
doSomething() {
},
// old way
something: something,
// new way
something
};Constants
ES5 - The old way
var SOMETHING_IMPORTANT = 1;
SOMETHING_IMPORTANT = 2;
SOMETHING_IMPORTANT === 1; // falseES5 - The actual old way
Object.defineProperty(window, "SOMETHING_IMPORTANT", {
value: 1,
writable: false,
configurable: false
});ES6 - The new way
const SOMETHING_IMPORTANT = 1;
SOMETHING_IMPORTANT = 2;
SOMETHING_IMPORTANT === 1; // trueES6 - Constant anythings
const IMPORTANT_FUNCTION = function() {
return 'Anything can be assigned to constants';
};Block Scoping
ES5 - Two kinds of scope
var i = 1;
if(i) {
var i = 2;
}
i === 1; // falseES6 - Three kinds of scope
let i = 1;
if(i) {
let i = 2;
}
i === 1; // trueES5 - Two kinds of scope
function foo() {
return 1;
}
{
function foo() {
return 2;
}
foo() === 2; // true
}
foo() === 1; // falseES6 - Three kinds of scope
function foo() {
return 1;
}
{
function foo() {
return 2;
}
foo() === 2; // true
}
foo() === 1; // trueArrow Functions
ES5 - Anonymous functions
(function(x, y, z) {
x++;
return x + y + z;
});ES6 - Shorter syntax
(x, y, z) => {
x++;
return x + y + z;
};ES6 - Even shorter syntax
(x, y, z) => x + y + z;ES5 - Remember this?
function foo() {
var that = this;
setTimeout(function() {
return that.something;
}, 200);
}ES5 -Slightly better
function foo() {
setTimeout(function() {
return this.something;
}.bind(this), 100);
}ES6 - Inherit scope
function foo() {
setTimeout(() => this.something, 100);
}Parameters
ES5 - "default" params
function foo(x, y) {
if(!x) {
x = 10;
}
if(!y) {
y = 15;
}
return x + y;
}ES6 - Actual defaults
function foo(x = 10, y = 15) {
return x + y;
}ES6 - Rest params
function foo(x, ...y) {
return x + y.length;
}
foo('Digital Surgeons',1,2,3,4,5) // Digital Surgeons5ES5 - "Rest" params
function foo(x) {
var y = Array.prototype.slice.call(arguments, 1);
return x + y.length;
}
foo('Digital Surgeons',1,2,3,4,5) // Digital Surgeons5ES6 - Spread params
function foo() {
return arguments.length;
}
var params = [4, 5, 6];
foo('Digital Surgeons', ...params); // 4ES5 - "Spread" params
function foo() {
return arguments.length;
}
var params = [4, 5, 6];
foo.apply(undefined, ['Digital Surgeons'].concat(params)); // 4Template Strings
ES6 Has Templates!

ES5 - String concat hell
var player = {
name: 'Harry Kane',
team: 'Spurs',
goals: 21
},
message = player.name + ' of ' +
player.team + ' scored ' +
player.goals + ' in 2014/15'; ES6 - Native templating
let player = {
name: 'Harry Kane',
team: 'Spurs',
goals: 21
},
message = `${player.name} of ${player.team} scored ${player.goals} in 2014/15`; ES6 - Line breaks ftw
let player = {
name: 'Harry Kane',
team: 'Spurs',
goals: 21
},
message = `${player.name} of
${player.team} scored
${player.goals} in 2014/15`;
// Harry Kane of
// Spurs scored
// 21 in 2014/15Modules
ES6 Has Modules!!

ES5 - Browserify
// utils.js
module.exports.add(x, y) {
return x + y;
}
module.exports.subtract(x, y) {
return x - y;
}
// something.js
var utils = require('lib/utils.js');
utils.add(1, utils.subtract(3, 1)) // 3ES6 - Native modules
// utils.js
export add(x, y) {
return x + y;
}
export subtract(x, y) {
return x - y;
}
// something.js
import add from 'lib/utils.js';
add(1, 2) // 3
// something-else.js
import * from 'lib/utils.js';
add(1, subtract(3, 1)) // 3Classes
ES6 Has Classes!!

Kinda
ES5 - Object Oriented JS
function MyClass(name) {
if(!name) {
name = 'Chambaz';
}
this.tmpl = 'Hello ';
this.name = name;
}
MyClass.prototype.printName = function() {
return this.tmpl+this.name;
};
var myClass = new MyClass('Digital Surgeons');
myClass.printName(); // Hello Digital SurgeonsES6 - Syntatic Sugar
class MyClass {
constructor(name = 'Chambaz') {
this.tmpl = 'Hello ';
this.name = name;
}
printName() {
return this.tmpl+this.name;
}
}
var myClass = new MyClass('Digital Surgeons');
myClass.printName(); // Hello Digital SurgeonsES5 - Prototypal Inheritance
// have to redefine constructor
function MyOtherClass(name) {
if(!name) {
name = 'Chambaz';
}
this.tmpl = 'Hello ';
this.name = name;
}
MyOtherClass.prototype = Object.create(MyClass.prototype);
MyOtherClass.prototype.constructor = MyOtherClass;
MyOtherClass.prototype.printNameNew = function() {
return this.printName()+', how\'d you like dat inheritence doe';
};
var myOtherClass = new MyOtherClass('Digital Surgeons');
myOtherClass.printNameNew(); // Hello Digital Surgeons, how'd you like dat inheritence doeES6 - Syntatic sugar
class MyOtherClass extends MyClass {
printName() {
let printed = super.printName();
return `${printed}, how'd you like dat ES6 doe`;
}
}
var myOtherClass = new MyOtherClass('Digital Surgeons');
myOtherClass.printName(); // Hello Digital Surgeons, how'd you like dat ES6 doeES5 - Static methods
function MyClass(name) {
if(!name) {
name = 'Chambaz';
}
this.tmpl = 'hello ';
this.name = name;
}
MyClass.doSomethingNow = function() {
return 'Alright, call it soccer then';
};
MyClass.doSomethingNow(); // Alright, call it soccer thenES6 - Syntatic sugar
class MyClass {
constructor(name = 'Chambaz') {
this.tmpl = 'Hello ';
this.name = name;
}
printName() {
return this.tmpl+this.name;
}
static doSomethingNow() {
return 'Alright, call it soccer then';
}
}
myClass.doSomethingNow(); // Alright, call it soccer thenES5 - Getters / setters
var myObj = {
a: 10,
get b() {
return this.a + 1;
},
set c(x) {
this.a = this.a + x;
}
};
myObj.b // 11
myObj.c = 10;
myObj.a // 20ES6 - True getters / setters
class MyClass {
constructor(a = 10) {
this.a = a;
}
get a() {
return this.a + 1;
}
set b(x) {
this.b = this.a + x;
}
}
var myClass = new MyClass(1);
myClass.a // 2
myClass.b = 10;
myClass.b // 11Disclaimer
I don't know what I'm talking about

Symbols
ES6 - New primitive type
let symbol1 = Symbol();
let symbol2 = Symbol('Digital Surgeons');
let symbol3 = Symbol('Digital Surgeons');
typeof symbol1 // symbol
symbol1 === symbol2 // false
symbol2 === symbol3 // false
ES6 - Hidden properties
let mySymbol = Symbol('Description');
let obj = {
// property key is a symbol
[mySymbol] : 'Something',
// defined inline
[Symbol('key')] : 123,
something : 'Digital',
else: 'Surgeons'
};
Object.getOwnPropertyNames(obj); // [something, else]
Object.getOwnPropertySymbols(obj); // [Symbol('Description'), Symbol('key')]Iterators
ES6 - Custom iteration
let obj = {
data: ['Digital', 'Surgeons'],
[Symbol.iterator]() {
const self = this;
let index = 0;
return {
next() {
if (index < self.data.length) {
return {
value: `We are ${self.data[index++]}`
};
} else {
return { done: true };
}
}
};
}
};ES6 - Custom iteration
for (let x of obj) {
console.log(x);
}
// We are Digital
// We are SurgeonsGenerators
ES6 - Cooperative functions
function *foo() {
var x = 1 + (yield "foo");
return x;
}
foo() // NOTHING!ES6 - Generator Iterator
function *foo() {
var x = 1 + (yield "foo");
return x;
}
var something = foo();
something.next(); // { value: "foo", done: false }
something.next(10); // { value: 11, done: true }ES6 - Remember iterators
function *foo() {
yield 1;
yield 2;
yield 3;
yield 4;
return 5;
}
for(let x of foo()) {
console.log(x); // 1, 2, 3, 4, 5
}ES6 - Delegating generators
function *foo() {
yield 3;
yield 4;
}
function *bar() {
yield 1;
yield 2;
yield *foo(); // `yield *` delegates iteration control to `foo()`
yield 5;
}
for (var v of bar()) {
console.log(v);
}
// 1 2 3 4 5Wait for it...
Async Generators
// handle AJAX request and call next() when complete
function request(url) {
$.get(url, function(response){
it.next(response);
});
}
// async generator
function *main() {
// pause here until the first request completes
var result1 = yield request("http://some.url.1");
var data = JSON.parse(result1);
// pause here until second request completes
var result2 = yield request("http://some.url.2?id=" + data.id);
var resp = JSON.parse( result2 );
console.log( "The value you asked for: " + resp.value );
}
// get it all started
var it = main();
it.next();Waaaaa?!
...and many more!
Math Functions
Math.sign(-8) // -1
Math.sign(3) // 1
Math.trunc(3.1) // 3
Math.cbrt(8) // 2
String Functions
'Digital Surgeons'.startsWith('Digital') // true
'Digital Surgeons'.endsWith('Surgeons') // true
'Digital Surgeons'.includes('Surge') // true...plus

Mooney's FavoUrite
'Mooney '.repeat(999);
/*
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney
Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney Mooney MooneyFurther reading
Hack time!

ES6
By Adam Chambers
ES6
- 1,053