Exploring ES6
Playground
4 npm install babel-node
4 http://babeljs.io/repl
4 chrome://flags/#enable-javascript-harmony
4 Scratchpad in Firefox
Favourite ES6 features
https://docs.google.com/forms/d/
1bhmqePIstN9NNxK4QX1-F8XJcJ8C0HdPao01gAAoh3I/
viewanalytics
-- Axel Rauschmayer
Begin from some sugar syntax
4 Classes
4 Modules
4 Arrow functions
4 Template literal
4 Destructuring
Classes
// ES3
var inherit = (function() {
var F = function() {}
return function(C, P) {
F.prototype = P.prototype
C.prototype = new F
C.prototype.constructor = C
}
})()
function Overlay(options) {}
function Dialog(options) {
Overlay.call(this, options)
}
inherit(Dialog, Overlay)
Classes
// ES5
function Dialog(options) {
Overlay.call(this, options)
}
Dialog.prototype = Object.create(Overlay.prototype)
Dialog.prototype.constructor = Overlay
Classes
// ES6
class Overlay {
constructor(options) {}
}
class Dialog extends Overlay {
constructor(options) {
super(options)
}
open() {}
}
Classes
mixin
import mixin from 'mixin'
class Overlay {
constructor(options) {}
}
class Dialog extends mixin(Overlay, EventEmitter) {
constructor(options) {
super(options)
}
open() {}
}
Classes
// getter/setter
class Polygon {
constructor(height, width) {
this.height = height
this.width = width
}
get area() {
return this.calcArea()
}
calcArea() {
return this.height * this.width
}
}
Classes
// static methods
class Point {
constructor(x, y) {
this.x = x
this.y = y
}
static distance(a, b) {
const dx = a.x - b.x
const dy = a.y - b.y
return Math.sqrt(dx * dx + dy * dy)
}
}
Modules
// CommonJS
// export
// animationFrame.js
module.exports = {
requestAnimationFrame: window.requestAnimationFrame,
cancelAnimationFrame: window.cancelAnimationFrame
}
// import
var raf = require('./animationFrame').requestAnimationFrame
Modules
// es6
// export
export requestAnimationFrame
export cancelAnimationFrame
// import
import { requestAnimationFrame as raf, cancelAnimationFrame as caf } from './animationFrame'
// export
export default React
// import
import React, { Component } from 'react'
Arrow functions
()=>{}
Identifier => Expression
// ES5
var total = values.reduce(function (a, b) {
return a + b;
}, 0);
// ES6
var total = values.reduce((a, b) => a + b, 0);
Template
4 multiple lines
4 expression inside
`Error Code: ${exception.code},
Error Message: ${exception.message}`
Destructuring
// array
var [a, , b] = [1,2,3]
[a, b] = [b, a]
// object
let options = {closeOnPressingESC: false, closeOnClicking: true}
let { closeOnPressingESC: esc, closeOnClicking: click } = options
Setup
4 npm init
4 npm install webpack babel-loader
4 touch webpack.config.js
var webpack = require('webpack'),
path = require('path')
module.exports = {
entry: [
'./src/index.js'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
loaders: [{
loaders: ['babel'],
include: path.join(__dirname, 'src')
}]
}
}
More
4 Iterator
4 Generator
4 Proxy
Iterator
// for in (not recommended)
for (var index in values) {
console.log(values[index])
}
// for of
for (var value of values) {
console.log(value)
}
Iterator
Array, String, Map, Set, Array-like objects(NodeLists...)
Iterator
class RangeIterator {
constructor(start, stop) {
this.value = start
this.stop = stop
}
[Symbol.iterator]() { return this; }
next() {
var value = this.value
if (value < this.stop) {
this.value++
return {done: false, value: value}
} else {
return {done: true, value: undefined}
}
}
}
function range(start, stop) {
return new RangeIterator(start, stop)
}
Generator
function* range(start, stop) {
for (var i = start; i < stop; i++)
yield i
}
Generators are iterators.
All generators have a built-in implementation of .next()
and Symbol.iterator.
Generator
request('/api/user/~me', function(res) {
request('/api/statuses/' + res.id, function(res) {
// ...
})
})
Generator
function fetch(url) {
request(url, function(response){
it.next(response)
})
}
function *main() {
var result1 = yield fetch('/api/user/~me')
var result2 = yield request('/api/statuses/' + result1.id )
}
var it = main()
it.next()
Generator
function runGenerator(g) {
var it = g(), ret
(function iterate(val){
ret = it.next( val )
if (!ret.done) {
if ('then' in ret.value) {
ret.value.then( iterate )
}
else {
setTimeout( function(){
iterate( ret.value )
}, 0 )
}
}
})()
}
Generator
runGenerator(function *main(){
var result1 = yield fetch('/api/user/~me')
var result2 = yield fetch('/api/statuses/' + result1.id )
})
https://github.com/tj/co
Proxy
setter/getter in ES5
// ES5
var person = {}
Object.defineProperty(person, 'age', {
set: function(value) {
if (value > 200) {
throw new RangeError('seems invalid')
}
}
})
Proxy
setter/getter, the different way
let validator = {
set(obj, prop, value) {
if (prop === 'age') {
if (!Number.isInteger(value)) {
throw new TypeError('The age is not an integer')
}
if (value > 200) {
throw new RangeError('The age seems invalid')
}
}
// The default behavior to store the value
obj[prop] = value
}
}
let person = new Proxy({}, validator)
Proxy
new Proxy(target, handler)
4 handler.getPrototypeOf()
4 handler.setPrototypeOf()
4 handler.isExtensible()
4 handler.preventExtensions()
4 handler.getOwnPropertyDescriptor()
Proxy
4 handler.defineProperty()
4 handler.has()
4 handler.get()
4 handler.set()
4 handler.deleteProperty()
4 handler.enumerate()
4 handler.ownKeys()
Proxy
4 handler.apply()
4 handler.construct()
References
4 ES6 in depth
4 Learn ECMAScript 6 inside and out
4 Meta programming with ECMAScript 6 proxies

Exploring ES6