SlideShare a Scribd company logo
ES6
Next Generation Javascript
By Ramesh Nair and Grégoire Charvet
https://github.com/hiddentao/es6-slides
Speakers
Grégoire Charvet (geekingfrog.com)
Full time node.js developper
Passionate about the web
Working on the web for almost 2 years now
Ramesh Nair (hiddentao.com)
Full time Javascript/Node developper
Also worked with PHP, Python, Java, C++
Loves optimizing for performance
Rapid history of javascript
The birth

Created in 10 days in 1995 (by Brendan Eich) at Netscape
Brought to ECMA a year later to standardize it
javaScript has nothing to do with java
Early history

ECMAScript 2 in 98, 3 in 99
War with Microsoft -> ES4 has never been adopted
In 2005, Microsoft introduced ajax
In 2009, all parties agreed to move forward with ES5 +
harmony process
Now

Javascript most well known implementation of ECMAScript
(with ActionScript)
Javascript is the assembly of the web
Confusing version number, JS 1.8 correspond to ES6
ES6

ES6 work started in 2011
As of now (Feb 2014), ES6 is not yet adopted (but it's almost
there)
Major milestone
Not 'production ready' yet
What we will cover today
Support
Scope and control
Iterators and Generators
Collections
Typed objects
Direct proxies
Template strings
API improvements
Modularity
Support
24

30

✗

For chrome, need to enable the experimental js features
full table
Node.js support
Node.js: get the latest 0.11 and add the flag --harmony
Support is the same as chrome (V8)
Safari support
Almost the same as IE (so quasi inexistant)
Scoping
24

30

11
Block scoping
Finally !
Before
for(var i=10; i>0 ; i--) {
// do stuff with i
}
console.log(i); // 0
let
for(let i=10; i>10; i--) {
}
console.log(i); // `i is not defined`
Works with if too
var log = function(msg) {};
if(someCond) {
let log = Math.log;
// do some stuff
}
log("I'm done here");
Easier closures
broken example
var a = ['rhum', 'banana', 'nutella'];
for(var i = 0, n=a.length; i<n; i++) {
var nomnom = a[i];
setTimeout(function() {
console.log(nomnom);
}, 500*(i+1))
}
Easy fix
var a = ['rhum', 'banana', 'nutella'];
for(var i = 0, n=a.length; i<n; i++) {
let nomnom = a[i];
setTimeout(function() {
console.log(nomnom);
}, 500*(i+1))
}
let('s) recap

works like var
scope is defined by the current block ({ })
const
Like let , but define read-only constant declarations.
'use strict';
const i = 10;
i = 5; // throw error
Destructuration
24

✗

✗
With array
// Assignment
var [day, month, year] = [19, 02, 2014];
// Swap two values.
var x=3, y=4;
[x, y] = [y, x];
Array with functions
var now = function() { return [19, 02, 2014]; }
var [day, month] = now();
var [, , year] = now();
With objects
var now = function() { return {
d: 19,
m: 2,
y: 2014
}}
var {d: day, m: month} = now();
// day: 19
// month: 2
As argument of a function
recipes = [
{ name: 'burger', calorie: 215 },
{ name: 'pizza', calorie: 266 } ];
recipes.forEach(function
({ name: name, calorie: calorie }) {
console.log(name, calorie);
}
);
Default function parameters
24

30

✗
Ability to define default value for functions
paramaters.
No more:
function(a) {
if(!a) { a = 10; }
// do stuff with a
}
Now
function(a=10) {
// do stuff with a
}
Undefined and null
undefined will trigger the evaluation of the default value,
not null
function point (x, y=1, z=1) {
return console.log(x, y, z);
}
point(10, null); // 10, null, 1
Arity
Number of parameters without default value
(function(a){}).length // 1
(function(a=10){}).length // 0
(function(a=10, b){}).length // 1
Rest parameters
24

✗

✗
Better than arguments
function(name) {
console.log(name);
arguments[0] = 'ME !';
console.log(name); // ME !
Array.isArray(arguments); // false
}
Now
function(...args) {
Array.isArray(args); // true
// do some stuff
}
function(name, ...more) {
}
Example
var humblify = function(name, ...qualities) {
console.log('Hello %s', name);
console.log('You are '+qualities.join(' and '));
}
humblify('Greg', 'awesome', 'the master of the universe');
// Hello Greg
// You are awesome and the master of the universe
Restrictions
Rest parameters can only be the last parameter
// incorrect
function(...args, callback) {
}
Details
Rest parameter is always an array
function f(name, ...more) {
Array.isArray(more); // always true
return more.length;
}
f(); // returns 0
Arity
Does not include the rest parameter
(function(a) {}).length // 1
(function(a, ...rest) {}).length // 1
Spread
24 (with array)
27-28 (with functions)

✗

✗
Expand expression where multiple
arguments or multiple element are needed
More powerful array
manipulation
Usecase: create new array with an existing one inside it:
var from = [1, 2];
// wants: [0, 1, 2, 3] ie [0, from, 3]
With es5
a.unshift(0);
a.push(3);
// and splice is here also

With es6

var total = [0, ...from, 3];
Converting any array-like
Array like ???

Object with a length property
Can access elements with []
var fake = {
0: 'I am',
1: 'not',
2: 'an aray',
length: 3
};
Array like in the wild
Function's arguments
All nodeList from the DOM
Before:
var nodes = document.querySelectorAll('p');
var nodes = [].slice.call(nodes);
And now:
nodes = [...nodes];
Array conversion
Better way:
Array.from(document.querySelectorAll('p'));
Out of the scope of the talk.
Spread with functions
A better apply

var f = function(one, two, three) {}
var a = [1, 2, 3];
f.apply(null, a);
Apply ?
Function.prototype.apply
fun.apply(thisArg, [argsArray])
Apply example
function f() {
for(let i=0; i<arguments.length; ++i)
console.log(arguments[i]);
}
f.apply(this, ['one', 2, 'foo']);
// one
// 2
// foo
With es6's spread
var f = function(one, two, three) {}
var a = [1, 2, 3];
f(...a);
Sweet syntax
var f = function(a, b, c, d, e, f) {};
var a = [1, 2];
f(-1, ...a, 3, ...[-3, -4]);
Apply for new
With es5, one cannot use apply with new .
var Constructor = function() {
// do some stuff
}
var c = new Constructor.apply({}, []); //invalid

But now:
var dataFields = readDateFields(database);
var d = new Date(...dateFields);
Better push
To push multiple elements:
var a = [];
var toPush = [1, 2, 3];
a.push.apply(a, toPush);
And now:
a.push(...toPush);
Next...

Iterators
24

✗

✗
An iterator lets you iterate over the contents of an object.
In ES6, an iterator is an object with a next() method which
returns {done, value} tuples.
An iterable is an object which can return an iterator.
Arrays are iterable:
var a = [1,2,3],
i = a.iterator();
console.log(i.next());
console.log(i.next());
console.log(i.next());
console.log(i.next());

//
//
//
//

{done:
{done:
{done:
{done:

false, value: 1}
false, value: 2}
false, value: 3}
true, value: undefined}
The for-of loop can be used to simplify iterations:
var a = [1,2,3];
for (var num of a) {
console.log(num); // 1, 2, 3
}
Array comprehensions:
var a = [
{ color: 'red' },
{ color: 'blue' }
];
[ x.color for (x of a) if ('blue' === x.color) ]
// [ 'blue' ]
We can make any object iterable:

function ClassA() {
this.elements = [1, 2, 3];
}
By adding the @@iterator method:
ClassA.prototype['@@iterator'] = function() {
return {
elements: this.elements,
index: 0,
next: function() {
if (this.index >= this.elements.length)
return {
done: true,
value: undefined
};
else
return {
done: false,
value: this.elements[this.index++]
};
}}};
We can iterate over the Object:

var col = new ClassA();
for (var num of col) {
console.log(num); // 1, 2, 3
}
Generators
27

30

✗
A generator is a special type of iterator.
A generator provides a throw() method. Its next()
method accepts a parameter.
A generator function acts as a constructor for a generator.
Generators offer a clean way of doing asynchronous
programming!
Simple example:
var helloWorld = function*() {
yield 'hello';
yield 'world';
}
var hw = helloWorld();
console.log( hw.next() ); // { value: 'hello', done: false }
console.log( hw.next() ); // { value: 'world', done: false }
console.log( hw.next() ); // { value: undefined, done: true }
Passing values back to generator:
var helloWorld = function*() {
var nextWord = yield 'hello';
yield nextWord;
}
var hw = helloWorld();
console.log( hw.next() );
// { value: 'hello', done: false }
console.log( hw.next('world') ); // { value: 'world', done: false }
console.log( hw.next() );
// { value: undefined, done: true }
Let's take it step-by-step to see how code gets suspended...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
Yield 2...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
Yield 2...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
Yield 2...
{ done: false, value: 'world'
}
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
Yield 2...
{ done: false, value: 'world'
}
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
Yield 2...
{ done: false, value: 'world'
}
No more yields...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}

Yield 1...
{ done: false, value: 'hello'
}
Yield 2...
{ done: false, value: 'world'
}
No more yields...
{ done: true, value: undefined
}

var hw = helloWorld();
console.log( hw.next() );
console.log( hw.next('world') );
console.log( hw.next() );
The code in the generator doesn't start executing until you say
so.
When the yield statement is encountered it suspends
execution until you tell it to resume.
What about throw() -ing errors?
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );

Yield 1...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );

Yield 1...
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
var helloWorld = function*() {
console.log('Yield 1...');
var nextWord = yield 'hello';
console.log('Yield 2...');
yield nextWord;
console.log('No more yields...');
}
var hw = helloWorld();
console.log( hw.next() );
console.log( hw.throw('Voldemort')
);
console.log( hw.next() );

Yield 1...
{ done: false, value: 'hello'
}
Error: Voldemort
How do Generators make asynchronous programming easier?
The old-school way:
var readFile = function(fileName, cb) { ... };
var main = function(cb) {
readFile('file1', function(err, contents1) {
if (err) return cb(err);
console.log(contents1);
readFile('file2', function(err, contents2) {
if (err) return cb(err);
console.log(contents2);
cb();
});
});
}
main(console.error);
Improved using Promises:
var readFile = Promise.promisify(function(fileName, cb) { ... });
var main = function() {
return readFile('file1')
.then(function(contents) {
console.log(contents);
return readFile('file2');
})
.then(function(contents) {
console.log(contents);
})
.catch(console.error);
}
main();
We can do better with generators.
But first we need a function which will automatically handle
the yield -ed values and call next() on the generator...
Automatically resolve Promises and call next() :
var runGenerator = function(generatorFunction) {
var gen = generatorFunction();
var gNext = function(err, answer) {
if (err) return gen.throw(err);
var res = gen.next(answer);
if (!res.done) {
Promise.resolve(res.value)
.then(function(newAnswer) {
gNext(null, newAnswer);
})
.catch(gNext);
}
};
gNext();
}
Now we can rewrite main() as a generator function:
var readFile = Promise.promisify(function(fileName, cb) { ... });
var main = function*() {
try {
console.log( yield readFile('file1') );
console.log( yield readFile('file2') );
} catch (err) {
console.error(err);
}
}
runGenerator(main);
You don't need to write runGenerator() yourself.
https://github.com/visionmedia/co - similar to
runGenerator but more powerful.
https://github.com/petkaantonov/bluebird - kick-ass
Promise library and provides runGenerator-like methods.
Generator delegation:
var inner = function*() {
try {
yield callServer1();
yield callServer2();
} catch (e) {
console.error(e);
}
};

var outer = function*() {
try {
yield callServer1();
yield callServer2();
} catch (e) {
console.error(e);
}
};

var outer = function*() {
yield* inner();
};

runGenerator(outer);

runGenerator(outer);
Generator comprehension:
(for (x of a)
for (y of b)
x * y)

(function* () {
for (x of a) {
for (y of b) {
yield x * y;
}
}
}())
Generators = future of JS asynchronous programming.
...and ES6 also has Promises!
http://spion.github.io/posts/why-i-am-switching-topromises.html
Next...

Collections
24

30

11
Set - no duplicates allowed
var items = new Set();
items.add(5);
items.add("5");
items.add(5);
console.log(items.size);

// 2

var items = new Set([1,2,3,4,5,5,5]);
console.log(items.size);
// 5
Modifying a Set
var items = new Set([1,2,3,4,4]);
console.log( items.has(4) ); // true
console.log( items.has(5) ); // false
items.delete(4);
console.log( items.has(4) ); // false
console.log( items.size ); // 3
items.clear();
console.log( items.size ); // 0
Iterate over a Set using for-of
var items = new Set([1,2,3,4,4]);
for (let num of items) {
console.log( num );
}

// 1, 2, 3, 4
Map - map from key to value
var map = new Map();
map.set("name", "John");
map.set(23, "age");
console.log( map.has(23); ) // true
console.log( map.get(23) ); // "age"
console.log( map.size );
// 2
Map vs Object
Maps can have non-string keys
Maps don't have prototype leakage issues, i.e. no need to
use hasOwnProperty()
But
Modifying a Map
var map = new Map([ ['name', 'John'], [23, 'age'] ]);
console.log( map.size );
// 2
map.delete(23);
console.log( map.get(23) ); // undefined
map.clear();
console.log( map.size ); // 0
Iterating over a Map
var map = new Map([ ['name', 'John'], [23, 'age'] ]);
for (var value of map.values()) { ... }
for (var key of map.keys()) { ... }
for (var item of map.items()) {
console.log('key: ' + item[0] + ', value: ' + item[1]);
}
for (var item of map) { // same as iterating map.items() }
map.forEach(function(value, key, map) { ... });
WeakMap - similar to Map , but...
Only allows Object keys
Only holds a reference to the Object used as a key, so it
doesn't prevent garbage collection
Do no provide a size
Cannot be iterated over
var weakMap = new WeakMap();
var key = {
stuff: true
};
weakMap.set(key, 123); // weakMap contains 1 item
delete key;

// weakMap is now empty
Next...

Typed objects
✗

✗

✗
Typed objects are similar to struct objects in C
They provide memory-safe, structured access to contiguous
data
They can expose a binary representation, making
serialization/de-serialization easy
Example: represent a 2D point
const Point2D = new StructType({
x: uint32,
y: uint32
});
Can access the underlying storage of the struct
let p = Point2D({x : 0, y : 0});
p.x = 5;
let arrayBuffer = Point.storage(p).buffer;
typeof arrayBuffer // ArrayBuffer
arrayBuffer.byteLength // 8
Hierarchy of typed objects
const Corner = new StructType({ point: Point2D });
const Triangle = Corner.dim(3);
let t = Triangle([{ point: { x: 0, y: 0 } },
{ point: { x: 5, y: 5 } },
{ point: { x: 10, y: 0 } }]);
t[0].point.x = 5;
A type object and all of its sub objects share the same memory

let t = Triangle([{ point: { x: 0, y: 0 } },
{ point: { x: 5, y: 5 } },
{ point: { x: 10, y: 0 } }]);
Triangle.storage(t).buffer.byteLength; // 24
Typed objects use copy-on-write
const Corner = new StructType({
point: Point2D
});
let p = Point2D({ x: 1, y: 1 });
let c = Corner({ point: {x: 2, y: 2} });
c.point = p; // p gets copied
c.point.x = 5;
p.x; // 1
Built-in value types
uint8, uint8Clamped
uint16
uint32
int8
int16
int32
float32
float64
boolean
string
Next...

Direct proxies
24

✗

✗
Direct proxies allows you to intercept calls made to a regular
object
They can wrap any Object , including Date ,
Function , etc.
Proxies are meant to work 'transparently'
var target = [];
var handler = { get: function() {...} };
var p = Proxy(target, handler);
Object.prototype.toString.call(p) // "[object Array]"
Object.getPrototypeOf(p) // Array.prototype
typeof p // "object"
Array.isArray(p) // true
p[0] // triggers handler.get(target, "0", p)
p === target // false
Proxy handler can choose what to intercept
getOwnPropertyDescriptor
getOwnPropertyNames
getPrototypeOf
defineProperty
deleteProperty
freeze
seal
preventExtensions
isFrozen
isExtensible

isSealed
has
hasOwn
get
set
enumerate
keys
apply
construct
Next...

Template strings
✗

✗

✗
What template strings allow
Multi-line strings
String formatting - think printf from C
HTML escaping
Localization/internationalization
Basic substitution
var name = "Tom",
msg = `Hello, ${name}!`;
console.log(msg);

// "Hello, Tom!"
Expressions
var total = 30,
msg = `The total is ${total * 2} units`;
console.log(msg);

// "The total is 60 units"
Multi-line
var total = 30,
var msg = `The total is
${total * 2}
units`;
Functions
// Gets called with:
//
['Total is ', ' units']
//
60
var myFunc = function(literals) {
var str = '', i = 0;
while (i < literals.length) {
str += literals[i++];
if (i < arguments.length) { str += '[' + arguments[i] + ']'; }
}
return str;
};
var total = 30;
console.log( myFunc`Total is ${total * 2} units` );
// Total is [60] units
Next...

API improvements
24

✗

✗

with a few exceptions (full details)
New Math functions

log10 , log2 , log1p , expm1 , cosh , sinh , tanh ,
acosh , asinh , atanh , hypot , trunc , sign
Number
.isFinite()
.isNaN() - better than isNaN()
.isInteger()
.EPSILON - smallest values such that 1 +
Number.EPSILON > 1
String
.repeat(n) - copy current string n times
.startsWith(str)
.endsWith(str)
.contains(str)
.toArray() - same as .split('')
Next...

Modularity
✗

✗

✗
Classes
In es5

Classes doesn't exist natively
Prototype based inheritance
Framework and libraries implement their own class system
New keyword
class Laptop {
constructor() {
this.brand = 'asus';
}
on() { ... }
off() { ... }
}
Call the parent
class SmashedLaptop extend Laptop {
constructor() {
super();
this.pieces = [];
}
}
Key points

constructor replace the function definition in es5
No access to the prototype of the class
Methods are defined the same way as objects
Can call the parent with super (and perform initialization
within the constructor)
Modules
• import the default export of a module
import $ from "jquery";
• binding an external module to a variable
module crypto from "crypto";
• binding a module's exports to variables
import { encrypt, decrypt } from "crypto";
Modules
• binding & renaming one of a module's exports
import { encrypt as enc } from "crypto";
• re-exporting another module's exports
export * from "crypto";
• re-exporting specified exports
from another module
export { foo, bar } from "crypto";
Why ?

No need for the global object anymore
Works well with existing modules system (AMD,
CommonJS and node)
Simplicity and usability
Compatibility with browser and non-browser environments
Easy asynchronous external loading
Exporting and importing
module "chocolate" {
export let cocoa = 75;
}
In another file:
import { cocoa } from "chocolate";
// or
import { cocoa as c} from "chocolate";
Default export
module "foo" {
export default function() {console.log("Hi")}
}
import foo from "foo"; // no brackets
foo(); // Hi
Internals

Top-level variables stay inside the module
export make variables visible to the other modules
Can be read (get)
Cannot be changed (set)
Cannot be dynamically changed at runtime
Modules are recursively instantiated before evaluation
Modules' body is run after all dependencies are instantiated
That's all for
today!

See http://kangax.github.io/es5-compat-table/es6/ for more
Useful links

http://www.ecmascript.org/
http://www.esdiscuss.org/
https://developer.mozilla.org/en/docs/Web/JavaScript/ECMAScript

More Related Content

PDF
Explaining ES6: JavaScript History and What is to Come
Cory Forsyth
 
PDF
An Intro To ES6
FITC
 
PDF
ECMAScript 6
Piotr Lewandowski
 
PPTX
ES6 in Real Life
Domenic Denicola
 
PDF
ES2015 (ES6) Overview
hesher
 
PDF
EcmaScript 6 - The future is here
Sebastiano Armeli
 
ODP
EcmaScript 6
Manoj Kumar
 
ODP
ES6 PPT FOR 2016
Manoj Kumar
 
Explaining ES6: JavaScript History and What is to Come
Cory Forsyth
 
An Intro To ES6
FITC
 
ECMAScript 6
Piotr Lewandowski
 
ES6 in Real Life
Domenic Denicola
 
ES2015 (ES6) Overview
hesher
 
EcmaScript 6 - The future is here
Sebastiano Armeli
 
EcmaScript 6
Manoj Kumar
 
ES6 PPT FOR 2016
Manoj Kumar
 

What's hot (20)

PDF
JavaScript - new features in ECMAScript 6
Solution4Future
 
PPTX
Introduction to Ecmascript - ES6
Nilesh Jayanandana
 
PDF
Introduction into ES6 JavaScript.
boyney123
 
PDF
ES6 in Production [JSConfUY2015]
Guillermo Paz
 
PDF
JavaScript ES6
Leo Hernandez
 
PDF
Javascript ES6 generators
RameshNair6
 
PDF
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
PPTX
ES6: Features + Rails
Santosh Wadghule
 
PPTX
Modern JS with ES6
Kevin Langley Jr.
 
PDF
Planet-HTML5-Game-Engine Javascript Performance Enhancement
up2soul
 
PDF
Proxies are Awesome!
Brendan Eich
 
PPTX
Type Driven Development with TypeScript
Garth Gilmour
 
PDF
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
Fwdays
 
PDF
Rust ⇋ JavaScript
Ingvar Stepanyan
 
PDF
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
PPTX
EcmaScript unchained
Eduard Tomàs
 
PDF
Building fast interpreters in Rust
Ingvar Stepanyan
 
PDF
FalsyValues. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
PPTX
Category theory, Monads, and Duality in the world of (BIG) Data
greenwop
 
PDF
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
Wanbok Choi
 
JavaScript - new features in ECMAScript 6
Solution4Future
 
Introduction to Ecmascript - ES6
Nilesh Jayanandana
 
Introduction into ES6 JavaScript.
boyney123
 
ES6 in Production [JSConfUY2015]
Guillermo Paz
 
JavaScript ES6
Leo Hernandez
 
Javascript ES6 generators
RameshNair6
 
HelsinkiJS meet-up. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
ES6: Features + Rails
Santosh Wadghule
 
Modern JS with ES6
Kevin Langley Jr.
 
Planet-HTML5-Game-Engine Javascript Performance Enhancement
up2soul
 
Proxies are Awesome!
Brendan Eich
 
Type Driven Development with TypeScript
Garth Gilmour
 
"Немного о функциональном программирование в JavaScript" Алексей Коваленко
Fwdays
 
Rust ⇋ JavaScript
Ingvar Stepanyan
 
How to Clone Flappy Bird in Swift
Giordano Scalzo
 
EcmaScript unchained
Eduard Tomàs
 
Building fast interpreters in Rust
Ingvar Stepanyan
 
FalsyValues. Dmitry Soshnikov - ECMAScript 6
Dmitry Soshnikov
 
Category theory, Monads, and Duality in the world of (BIG) Data
greenwop
 
[Let'Swift 2019] 실용적인 함수형 프로그래밍 워크샵
Wanbok Choi
 
Ad

Viewers also liked (20)

PDF
ES2015 / ES6: Basics of modern Javascript
Wojciech Dzikowski
 
PDF
ES6: The Awesome Parts
Domenic Denicola
 
PDF
Lecture 2: ES6 / ES2015 Slide
Kobkrit Viriyayudhakorn
 
PDF
Lecture 3 - ES6 Script Advanced for React-Native
Kobkrit Viriyayudhakorn
 
PPTX
Real World Windows 8 Apps in JavaScript
Domenic Denicola
 
PDF
The ES6 Conundrum - All Things Open 2015
Christian Heilmann
 
PPTX
ES6 is Nigh
Domenic Denicola
 
PPTX
Creating Truly RESTful APIs
Domenic Denicola
 
PPTX
The Final Frontier
Domenic Denicola
 
PPTX
Client-Side Packages
Domenic Denicola
 
PPTX
JavaScript on the Desktop
Domenic Denicola
 
PPTX
Async Frontiers
Domenic Denicola
 
PDF
Boom! Promises/A+ Was Born
Domenic Denicola
 
PDF
Canvas de shooting 制作のポイント
Yohei Munesada
 
PDF
小規模案件で作られた秘伝のタレ
Muyuu Fujita
 
PDF
ノンゲーム系スマホアプリ制作 First Step
Yohei Munesada
 
PPTX
Domains!
Domenic Denicola
 
PPTX
Promises, Promises
Domenic Denicola
 
PPTX
今こそCSS 今こそfor you
Tatsuya Kosuge
 
PDF
最近、実務に導入してみたフロントエンドの技術8つの良かった点と反省点
Horiguchi Seito
 
ES2015 / ES6: Basics of modern Javascript
Wojciech Dzikowski
 
ES6: The Awesome Parts
Domenic Denicola
 
Lecture 2: ES6 / ES2015 Slide
Kobkrit Viriyayudhakorn
 
Lecture 3 - ES6 Script Advanced for React-Native
Kobkrit Viriyayudhakorn
 
Real World Windows 8 Apps in JavaScript
Domenic Denicola
 
The ES6 Conundrum - All Things Open 2015
Christian Heilmann
 
ES6 is Nigh
Domenic Denicola
 
Creating Truly RESTful APIs
Domenic Denicola
 
The Final Frontier
Domenic Denicola
 
Client-Side Packages
Domenic Denicola
 
JavaScript on the Desktop
Domenic Denicola
 
Async Frontiers
Domenic Denicola
 
Boom! Promises/A+ Was Born
Domenic Denicola
 
Canvas de shooting 制作のポイント
Yohei Munesada
 
小規模案件で作られた秘伝のタレ
Muyuu Fujita
 
ノンゲーム系スマホアプリ制作 First Step
Yohei Munesada
 
Promises, Promises
Domenic Denicola
 
今こそCSS 今こそfor you
Tatsuya Kosuge
 
最近、実務に導入してみたフロントエンドの技術8つの良かった点と反省点
Horiguchi Seito
 
Ad

Similar to ES6 - Next Generation Javascript (20)

PPTX
ES6 Overview
Bruno Scopelliti
 
PPTX
Es6 hackathon
Justin Alexander
 
KEY
JavaScript Growing Up
David Padbury
 
PDF
L5, Loop and iteration, CSE 202, BN11.pdf
SauravBarua11
 
PDF
Workshop 10: ECMAScript 6
Visual Engineering
 
PPTX
Getting started with ES6
Nitay Neeman
 
PDF
Say It With Javascript
Giovanni Scerra ☃
 
PPTX
Introducing PHP Latest Updates
Iftekhar Eather
 
PPT
Expert JavaScript tricks of the masters
Ara Pehlivanian
 
PPTX
ES6, 잘 쓰고 계시죠?
장현 한
 
PPTX
Groovy
Zen Urban
 
PPTX
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
PDF
Game Design and Development Workshop Day 1
Troy Miles
 
PDF
Internal workshop es6_2015
Miguel Ruiz Rodriguez
 
PPTX
Typescript barcelona
Christoffer Noring
 
KEY
Introduction to Groovy
André Faria Gomes
 
PDF
ES6 General Introduction
Thomas Johnston
 
PDF
JavaScript - Agora nervoso
Luis Vendrame
 
PDF
Refactoring to Macros with Clojure
Dmitry Buzdin
 
PDF
TypeScript Introduction
Dmitry Sheiko
 
ES6 Overview
Bruno Scopelliti
 
Es6 hackathon
Justin Alexander
 
JavaScript Growing Up
David Padbury
 
L5, Loop and iteration, CSE 202, BN11.pdf
SauravBarua11
 
Workshop 10: ECMAScript 6
Visual Engineering
 
Getting started with ES6
Nitay Neeman
 
Say It With Javascript
Giovanni Scerra ☃
 
Introducing PHP Latest Updates
Iftekhar Eather
 
Expert JavaScript tricks of the masters
Ara Pehlivanian
 
ES6, 잘 쓰고 계시죠?
장현 한
 
Groovy
Zen Urban
 
Callbacks, Promises, and Coroutines (oh my!): Asynchronous Programming Patter...
Domenic Denicola
 
Game Design and Development Workshop Day 1
Troy Miles
 
Internal workshop es6_2015
Miguel Ruiz Rodriguez
 
Typescript barcelona
Christoffer Noring
 
Introduction to Groovy
André Faria Gomes
 
ES6 General Introduction
Thomas Johnston
 
JavaScript - Agora nervoso
Luis Vendrame
 
Refactoring to Macros with Clojure
Dmitry Buzdin
 
TypeScript Introduction
Dmitry Sheiko
 

More from RameshNair6 (6)

PDF
solUI Introduction (2019)
RameshNair6
 
PDF
Kickback - incentivizing event attendance through crypto economics
RameshNair6
 
PDF
Introduction to Blockchains
RameshNair6
 
PDF
Introduction to PhoneGap
RameshNair6
 
PDF
Introduction to Dart
RameshNair6
 
ODP
Javascript Update May 2013
RameshNair6
 
solUI Introduction (2019)
RameshNair6
 
Kickback - incentivizing event attendance through crypto economics
RameshNair6
 
Introduction to Blockchains
RameshNair6
 
Introduction to PhoneGap
RameshNair6
 
Introduction to Dart
RameshNair6
 
Javascript Update May 2013
RameshNair6
 

Recently uploaded (20)

PDF
This slide provides an overview Technology
mineshkharadi333
 
PDF
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
PDF
Software Development Methodologies in 2025
KodekX
 
PPTX
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
PPTX
Coupa-Overview _Assumptions presentation
annapureddyn
 
PPTX
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
 
PDF
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
PPTX
IoT Sensor Integration 2025 Powering Smart Tech and Industrial Automation.pptx
Rejig Digital
 
PDF
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
PPTX
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
PDF
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
PDF
Beyond Automation: The Role of IoT Sensor Integration in Next-Gen Industries
Rejig Digital
 
PPTX
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
PDF
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
PDF
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
PDF
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
PDF
Research-Fundamentals-and-Topic-Development.pdf
ayesha butalia
 
PPTX
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
PPTX
ChatGPT's Deck on The Enduring Legacy of Fax Machines
Greg Swan
 
PPTX
AI and Robotics for Human Well-being.pptx
JAYMIN SUTHAR
 
This slide provides an overview Technology
mineshkharadi333
 
Unlocking the Future- AI Agents Meet Oracle Database 23ai - AIOUG Yatra 2025.pdf
Sandesh Rao
 
Software Development Methodologies in 2025
KodekX
 
Comunidade Salesforce São Paulo - Desmistificando o Omnistudio (Vlocity)
Francisco Vieira Júnior
 
Coupa-Overview _Assumptions presentation
annapureddyn
 
Dev Dives: Automate, test, and deploy in one place—with Unified Developer Exp...
AndreeaTom
 
The Evolution of KM Roles (Presented at Knowledge Summit Dublin 2025)
Enterprise Knowledge
 
IoT Sensor Integration 2025 Powering Smart Tech and Industrial Automation.pptx
Rejig Digital
 
BLW VOCATIONAL TRAINING SUMMER INTERNSHIP REPORT
codernjn73
 
The-Ethical-Hackers-Imperative-Safeguarding-the-Digital-Frontier.pptx
sujalchauhan1305
 
Cloud-Migration-Best-Practices-A-Practical-Guide-to-AWS-Azure-and-Google-Clou...
Artjoker Software Development Company
 
Beyond Automation: The Role of IoT Sensor Integration in Next-Gen Industries
Rejig Digital
 
OA presentation.pptx OA presentation.pptx
pateldhruv002338
 
How Open Source Changed My Career by abdelrahman ismail
a0m0rajab1
 
A Strategic Analysis of the MVNO Wave in Emerging Markets.pdf
IPLOOK Networks
 
Google I/O Extended 2025 Baku - all ppts
HusseinMalikMammadli
 
Research-Fundamentals-and-Topic-Development.pdf
ayesha butalia
 
cloud computing vai.pptx for the project
vaibhavdobariyal79
 
ChatGPT's Deck on The Enduring Legacy of Fax Machines
Greg Swan
 
AI and Robotics for Human Well-being.pptx
JAYMIN SUTHAR
 

ES6 - Next Generation Javascript

  • 1. ES6 Next Generation Javascript By Ramesh Nair and Grégoire Charvet https://github.com/hiddentao/es6-slides
  • 2. Speakers Grégoire Charvet (geekingfrog.com) Full time node.js developper Passionate about the web Working on the web for almost 2 years now Ramesh Nair (hiddentao.com) Full time Javascript/Node developper Also worked with PHP, Python, Java, C++ Loves optimizing for performance
  • 3. Rapid history of javascript
  • 4. The birth Created in 10 days in 1995 (by Brendan Eich) at Netscape Brought to ECMA a year later to standardize it javaScript has nothing to do with java
  • 5. Early history ECMAScript 2 in 98, 3 in 99 War with Microsoft -> ES4 has never been adopted In 2005, Microsoft introduced ajax In 2009, all parties agreed to move forward with ES5 + harmony process
  • 6. Now Javascript most well known implementation of ECMAScript (with ActionScript) Javascript is the assembly of the web Confusing version number, JS 1.8 correspond to ES6
  • 7. ES6 ES6 work started in 2011 As of now (Feb 2014), ES6 is not yet adopted (but it's almost there) Major milestone Not 'production ready' yet
  • 8. What we will cover today Support Scope and control Iterators and Generators Collections Typed objects Direct proxies Template strings API improvements Modularity
  • 9. Support 24 30 ✗ For chrome, need to enable the experimental js features full table
  • 10. Node.js support Node.js: get the latest 0.11 and add the flag --harmony Support is the same as chrome (V8)
  • 11. Safari support Almost the same as IE (so quasi inexistant)
  • 14. Before for(var i=10; i>0 ; i--) { // do stuff with i } console.log(i); // 0
  • 15. let for(let i=10; i>10; i--) { } console.log(i); // `i is not defined`
  • 16. Works with if too var log = function(msg) {}; if(someCond) { let log = Math.log; // do some stuff } log("I'm done here");
  • 17. Easier closures broken example var a = ['rhum', 'banana', 'nutella']; for(var i = 0, n=a.length; i<n; i++) { var nomnom = a[i]; setTimeout(function() { console.log(nomnom); }, 500*(i+1)) }
  • 18. Easy fix var a = ['rhum', 'banana', 'nutella']; for(var i = 0, n=a.length; i<n; i++) { let nomnom = a[i]; setTimeout(function() { console.log(nomnom); }, 500*(i+1)) }
  • 19. let('s) recap works like var scope is defined by the current block ({ })
  • 20. const Like let , but define read-only constant declarations. 'use strict'; const i = 10; i = 5; // throw error
  • 22. With array // Assignment var [day, month, year] = [19, 02, 2014]; // Swap two values. var x=3, y=4; [x, y] = [y, x];
  • 23. Array with functions var now = function() { return [19, 02, 2014]; } var [day, month] = now(); var [, , year] = now();
  • 24. With objects var now = function() { return { d: 19, m: 2, y: 2014 }} var {d: day, m: month} = now(); // day: 19 // month: 2
  • 25. As argument of a function recipes = [ { name: 'burger', calorie: 215 }, { name: 'pizza', calorie: 266 } ]; recipes.forEach(function ({ name: name, calorie: calorie }) { console.log(name, calorie); } );
  • 27. Ability to define default value for functions paramaters. No more: function(a) { if(!a) { a = 10; } // do stuff with a }
  • 28. Now function(a=10) { // do stuff with a }
  • 29. Undefined and null undefined will trigger the evaluation of the default value, not null function point (x, y=1, z=1) { return console.log(x, y, z); } point(10, null); // 10, null, 1
  • 30. Arity Number of parameters without default value (function(a){}).length // 1 (function(a=10){}).length // 0 (function(a=10, b){}).length // 1
  • 32. Better than arguments function(name) { console.log(name); arguments[0] = 'ME !'; console.log(name); // ME ! Array.isArray(arguments); // false }
  • 33. Now function(...args) { Array.isArray(args); // true // do some stuff } function(name, ...more) { }
  • 34. Example var humblify = function(name, ...qualities) { console.log('Hello %s', name); console.log('You are '+qualities.join(' and ')); } humblify('Greg', 'awesome', 'the master of the universe'); // Hello Greg // You are awesome and the master of the universe
  • 35. Restrictions Rest parameters can only be the last parameter // incorrect function(...args, callback) { }
  • 36. Details Rest parameter is always an array function f(name, ...more) { Array.isArray(more); // always true return more.length; } f(); // returns 0
  • 37. Arity Does not include the rest parameter (function(a) {}).length // 1 (function(a, ...rest) {}).length // 1
  • 38. Spread 24 (with array) 27-28 (with functions) ✗ ✗
  • 39. Expand expression where multiple arguments or multiple element are needed
  • 40. More powerful array manipulation Usecase: create new array with an existing one inside it: var from = [1, 2]; // wants: [0, 1, 2, 3] ie [0, from, 3]
  • 41. With es5 a.unshift(0); a.push(3); // and splice is here also With es6 var total = [0, ...from, 3];
  • 43. Array like ??? Object with a length property Can access elements with [] var fake = { 0: 'I am', 1: 'not', 2: 'an aray', length: 3 };
  • 44. Array like in the wild Function's arguments All nodeList from the DOM
  • 45. Before: var nodes = document.querySelectorAll('p'); var nodes = [].slice.call(nodes); And now: nodes = [...nodes];
  • 47. Spread with functions A better apply var f = function(one, two, three) {} var a = [1, 2, 3]; f.apply(null, a);
  • 49. Apply example function f() { for(let i=0; i<arguments.length; ++i) console.log(arguments[i]); } f.apply(this, ['one', 2, 'foo']); // one // 2 // foo
  • 50. With es6's spread var f = function(one, two, three) {} var a = [1, 2, 3]; f(...a);
  • 51. Sweet syntax var f = function(a, b, c, d, e, f) {}; var a = [1, 2]; f(-1, ...a, 3, ...[-3, -4]);
  • 52. Apply for new With es5, one cannot use apply with new . var Constructor = function() { // do some stuff } var c = new Constructor.apply({}, []); //invalid But now: var dataFields = readDateFields(database); var d = new Date(...dateFields);
  • 53. Better push To push multiple elements: var a = []; var toPush = [1, 2, 3]; a.push.apply(a, toPush); And now: a.push(...toPush);
  • 55. An iterator lets you iterate over the contents of an object. In ES6, an iterator is an object with a next() method which returns {done, value} tuples. An iterable is an object which can return an iterator.
  • 56. Arrays are iterable: var a = [1,2,3], i = a.iterator(); console.log(i.next()); console.log(i.next()); console.log(i.next()); console.log(i.next()); // // // // {done: {done: {done: {done: false, value: 1} false, value: 2} false, value: 3} true, value: undefined}
  • 57. The for-of loop can be used to simplify iterations: var a = [1,2,3]; for (var num of a) { console.log(num); // 1, 2, 3 }
  • 58. Array comprehensions: var a = [ { color: 'red' }, { color: 'blue' } ]; [ x.color for (x of a) if ('blue' === x.color) ] // [ 'blue' ]
  • 59. We can make any object iterable: function ClassA() { this.elements = [1, 2, 3]; }
  • 60. By adding the @@iterator method: ClassA.prototype['@@iterator'] = function() { return { elements: this.elements, index: 0, next: function() { if (this.index >= this.elements.length) return { done: true, value: undefined }; else return { done: false, value: this.elements[this.index++] }; }}};
  • 61. We can iterate over the Object: var col = new ClassA(); for (var num of col) { console.log(num); // 1, 2, 3 }
  • 63. A generator is a special type of iterator. A generator provides a throw() method. Its next() method accepts a parameter. A generator function acts as a constructor for a generator. Generators offer a clean way of doing asynchronous programming!
  • 64. Simple example: var helloWorld = function*() { yield 'hello'; yield 'world'; } var hw = helloWorld(); console.log( hw.next() ); // { value: 'hello', done: false } console.log( hw.next() ); // { value: 'world', done: false } console.log( hw.next() ); // { value: undefined, done: true }
  • 65. Passing values back to generator: var helloWorld = function*() { var nextWord = yield 'hello'; yield nextWord; } var hw = helloWorld(); console.log( hw.next() ); // { value: 'hello', done: false } console.log( hw.next('world') ); // { value: 'world', done: false } console.log( hw.next() ); // { value: undefined, done: true }
  • 66. Let's take it step-by-step to see how code gets suspended...
  • 67. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() );
  • 68. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() );
  • 69. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() );
  • 70. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() );
  • 71. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() );
  • 72. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1...
  • 73. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1...
  • 74. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' }
  • 75. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' }
  • 76. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' }
  • 77. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' } Yield 2...
  • 78. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' } Yield 2...
  • 79. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' } Yield 2... { done: false, value: 'world' }
  • 80. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' } Yield 2... { done: false, value: 'world' }
  • 81. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' } Yield 2... { done: false, value: 'world' } No more yields...
  • 82. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } Yield 1... { done: false, value: 'hello' } Yield 2... { done: false, value: 'world' } No more yields... { done: true, value: undefined } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.next('world') ); console.log( hw.next() );
  • 83. The code in the generator doesn't start executing until you say so. When the yield statement is encountered it suspends execution until you tell it to resume. What about throw() -ing errors?
  • 84. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() );
  • 85. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() );
  • 86. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() );
  • 87. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() );
  • 88. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() ); Yield 1...
  • 89. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() ); Yield 1...
  • 90. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' }
  • 91. var helloWorld = function*() { console.log('Yield 1...'); var nextWord = yield 'hello'; console.log('Yield 2...'); yield nextWord; console.log('No more yields...'); } var hw = helloWorld(); console.log( hw.next() ); console.log( hw.throw('Voldemort') ); console.log( hw.next() ); Yield 1... { done: false, value: 'hello' } Error: Voldemort
  • 92. How do Generators make asynchronous programming easier?
  • 93. The old-school way: var readFile = function(fileName, cb) { ... }; var main = function(cb) { readFile('file1', function(err, contents1) { if (err) return cb(err); console.log(contents1); readFile('file2', function(err, contents2) { if (err) return cb(err); console.log(contents2); cb(); }); }); } main(console.error);
  • 94. Improved using Promises: var readFile = Promise.promisify(function(fileName, cb) { ... }); var main = function() { return readFile('file1') .then(function(contents) { console.log(contents); return readFile('file2'); }) .then(function(contents) { console.log(contents); }) .catch(console.error); } main();
  • 95. We can do better with generators. But first we need a function which will automatically handle the yield -ed values and call next() on the generator...
  • 96. Automatically resolve Promises and call next() : var runGenerator = function(generatorFunction) { var gen = generatorFunction(); var gNext = function(err, answer) { if (err) return gen.throw(err); var res = gen.next(answer); if (!res.done) { Promise.resolve(res.value) .then(function(newAnswer) { gNext(null, newAnswer); }) .catch(gNext); } }; gNext(); }
  • 97. Now we can rewrite main() as a generator function: var readFile = Promise.promisify(function(fileName, cb) { ... }); var main = function*() { try { console.log( yield readFile('file1') ); console.log( yield readFile('file2') ); } catch (err) { console.error(err); } } runGenerator(main);
  • 98. You don't need to write runGenerator() yourself. https://github.com/visionmedia/co - similar to runGenerator but more powerful. https://github.com/petkaantonov/bluebird - kick-ass Promise library and provides runGenerator-like methods.
  • 99. Generator delegation: var inner = function*() { try { yield callServer1(); yield callServer2(); } catch (e) { console.error(e); } }; var outer = function*() { try { yield callServer1(); yield callServer2(); } catch (e) { console.error(e); } }; var outer = function*() { yield* inner(); }; runGenerator(outer); runGenerator(outer);
  • 100. Generator comprehension: (for (x of a) for (y of b) x * y) (function* () { for (x of a) { for (y of b) { yield x * y; } } }())
  • 101. Generators = future of JS asynchronous programming. ...and ES6 also has Promises! http://spion.github.io/posts/why-i-am-switching-topromises.html
  • 103. Set - no duplicates allowed var items = new Set(); items.add(5); items.add("5"); items.add(5); console.log(items.size); // 2 var items = new Set([1,2,3,4,5,5,5]); console.log(items.size); // 5
  • 104. Modifying a Set var items = new Set([1,2,3,4,4]); console.log( items.has(4) ); // true console.log( items.has(5) ); // false items.delete(4); console.log( items.has(4) ); // false console.log( items.size ); // 3 items.clear(); console.log( items.size ); // 0
  • 105. Iterate over a Set using for-of var items = new Set([1,2,3,4,4]); for (let num of items) { console.log( num ); } // 1, 2, 3, 4
  • 106. Map - map from key to value var map = new Map(); map.set("name", "John"); map.set(23, "age"); console.log( map.has(23); ) // true console.log( map.get(23) ); // "age" console.log( map.size ); // 2
  • 107. Map vs Object Maps can have non-string keys Maps don't have prototype leakage issues, i.e. no need to use hasOwnProperty() But
  • 108. Modifying a Map var map = new Map([ ['name', 'John'], [23, 'age'] ]); console.log( map.size ); // 2 map.delete(23); console.log( map.get(23) ); // undefined map.clear(); console.log( map.size ); // 0
  • 109. Iterating over a Map var map = new Map([ ['name', 'John'], [23, 'age'] ]); for (var value of map.values()) { ... } for (var key of map.keys()) { ... } for (var item of map.items()) { console.log('key: ' + item[0] + ', value: ' + item[1]); } for (var item of map) { // same as iterating map.items() } map.forEach(function(value, key, map) { ... });
  • 110. WeakMap - similar to Map , but... Only allows Object keys Only holds a reference to the Object used as a key, so it doesn't prevent garbage collection Do no provide a size Cannot be iterated over
  • 111. var weakMap = new WeakMap(); var key = { stuff: true }; weakMap.set(key, 123); // weakMap contains 1 item delete key; // weakMap is now empty
  • 113. Typed objects are similar to struct objects in C They provide memory-safe, structured access to contiguous data They can expose a binary representation, making serialization/de-serialization easy
  • 114. Example: represent a 2D point const Point2D = new StructType({ x: uint32, y: uint32 });
  • 115. Can access the underlying storage of the struct let p = Point2D({x : 0, y : 0}); p.x = 5; let arrayBuffer = Point.storage(p).buffer; typeof arrayBuffer // ArrayBuffer arrayBuffer.byteLength // 8
  • 116. Hierarchy of typed objects const Corner = new StructType({ point: Point2D }); const Triangle = Corner.dim(3); let t = Triangle([{ point: { x: 0, y: 0 } }, { point: { x: 5, y: 5 } }, { point: { x: 10, y: 0 } }]); t[0].point.x = 5;
  • 117. A type object and all of its sub objects share the same memory let t = Triangle([{ point: { x: 0, y: 0 } }, { point: { x: 5, y: 5 } }, { point: { x: 10, y: 0 } }]); Triangle.storage(t).buffer.byteLength; // 24
  • 118. Typed objects use copy-on-write const Corner = new StructType({ point: Point2D }); let p = Point2D({ x: 1, y: 1 }); let c = Corner({ point: {x: 2, y: 2} }); c.point = p; // p gets copied c.point.x = 5; p.x; // 1
  • 119. Built-in value types uint8, uint8Clamped uint16 uint32 int8 int16 int32 float32 float64 boolean string
  • 121. Direct proxies allows you to intercept calls made to a regular object They can wrap any Object , including Date , Function , etc.
  • 122. Proxies are meant to work 'transparently' var target = []; var handler = { get: function() {...} }; var p = Proxy(target, handler); Object.prototype.toString.call(p) // "[object Array]" Object.getPrototypeOf(p) // Array.prototype typeof p // "object" Array.isArray(p) // true p[0] // triggers handler.get(target, "0", p) p === target // false
  • 123. Proxy handler can choose what to intercept getOwnPropertyDescriptor getOwnPropertyNames getPrototypeOf defineProperty deleteProperty freeze seal preventExtensions isFrozen isExtensible isSealed has hasOwn get set enumerate keys apply construct
  • 125. What template strings allow Multi-line strings String formatting - think printf from C HTML escaping Localization/internationalization
  • 126. Basic substitution var name = "Tom", msg = `Hello, ${name}!`; console.log(msg); // "Hello, Tom!"
  • 127. Expressions var total = 30, msg = `The total is ${total * 2} units`; console.log(msg); // "The total is 60 units"
  • 128. Multi-line var total = 30, var msg = `The total is ${total * 2} units`;
  • 129. Functions // Gets called with: // ['Total is ', ' units'] // 60 var myFunc = function(literals) { var str = '', i = 0; while (i < literals.length) { str += literals[i++]; if (i < arguments.length) { str += '[' + arguments[i] + ']'; } } return str; }; var total = 30; console.log( myFunc`Total is ${total * 2} units` ); // Total is [60] units
  • 130. Next... API improvements 24 ✗ ✗ with a few exceptions (full details)
  • 131. New Math functions log10 , log2 , log1p , expm1 , cosh , sinh , tanh , acosh , asinh , atanh , hypot , trunc , sign
  • 132. Number .isFinite() .isNaN() - better than isNaN() .isInteger() .EPSILON - smallest values such that 1 + Number.EPSILON > 1
  • 133. String .repeat(n) - copy current string n times .startsWith(str) .endsWith(str) .contains(str) .toArray() - same as .split('')
  • 136. In es5 Classes doesn't exist natively Prototype based inheritance Framework and libraries implement their own class system
  • 137. New keyword class Laptop { constructor() { this.brand = 'asus'; } on() { ... } off() { ... } }
  • 138. Call the parent class SmashedLaptop extend Laptop { constructor() { super(); this.pieces = []; } }
  • 139. Key points constructor replace the function definition in es5 No access to the prototype of the class Methods are defined the same way as objects Can call the parent with super (and perform initialization within the constructor)
  • 140. Modules • import the default export of a module import $ from "jquery"; • binding an external module to a variable module crypto from "crypto"; • binding a module's exports to variables import { encrypt, decrypt } from "crypto";
  • 141. Modules • binding & renaming one of a module's exports import { encrypt as enc } from "crypto"; • re-exporting another module's exports export * from "crypto"; • re-exporting specified exports from another module export { foo, bar } from "crypto";
  • 142. Why ? No need for the global object anymore Works well with existing modules system (AMD, CommonJS and node) Simplicity and usability Compatibility with browser and non-browser environments Easy asynchronous external loading
  • 143. Exporting and importing module "chocolate" { export let cocoa = 75; } In another file: import { cocoa } from "chocolate"; // or import { cocoa as c} from "chocolate";
  • 144. Default export module "foo" { export default function() {console.log("Hi")} } import foo from "foo"; // no brackets foo(); // Hi
  • 145. Internals Top-level variables stay inside the module export make variables visible to the other modules Can be read (get) Cannot be changed (set) Cannot be dynamically changed at runtime Modules are recursively instantiated before evaluation Modules' body is run after all dependencies are instantiated
  • 146. That's all for today! See http://kangax.github.io/es5-compat-table/es6/ for more