Download - ES6 - Next Generation Javascript
ES6ES6Next Generation JavascriptNext Generation Javascript
By and Ramesh Nair Grégoire Charvet
https://github.com/hiddentao/es6-slides
SpeakersSpeakersGré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 javascriptRapid history of javascript
The birthThe birthCreated in 10 days in 1995 (by Brendan Eich) at NetscapeBrought to ECMA a year later to standardize itjavaScript has nothing to do with java
Early historyEarly historyECMAScript 2 in 98, 3 in 99War with Microsoft -> ES4 has never been adoptedIn 2005, Microsoft introduced ajaxIn 2009, all parties agreed to move forward with ES5 +harmony process
NowNowJavascript most well known implementation of ECMAScript(with ActionScript)Javascript is the assembly of the webConfusing version number, JS 1.8 correspond to ES6
ES6ES6ES6 work started in 2011As of now (Feb 2014), ES6 is not yet adopted (but it's almostthere)Major milestoneNot 'production ready' yet
What we will cover todayWhat we will cover todaySupportScope and controlIterators and GeneratorsCollectionsTyped objectsDirect proxiesTemplate stringsAPI improvementsModularity
SupportSupport
24 30 ✗
For chrome, need to enable the experimental js features
full table
Node.js supportNode.js supportNode.js: get the latest 0.11 and add the flag --harmony
Support is the same as chrome (V8)
Safari supportSafari supportAlmost the same as IE (so quasi inexistant)
ScopingScoping
24 30 11
Block scopingBlock scopingFinally !
BeforeBeforefor(var i=10; i>0 ; i--) { // do stuff with i}console.log(i); // 0
letletfor(let i=10; i>10; i--) {}console.log(i); // `i is not defined`
Works with if tooWorks with if toovar log = function(msg) {};if(someCond) { let log = Math.log; // do some stuff}log("I'm done here");
Easier closuresEasier closuresbroken 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 fixEasy fixvar 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) recaplet('s) recapworks like varscope is defined by the current block ({ })
constconstLike let , but define read-only constant declarations.
'use strict';const i = 10;i = 5; // throw error
DestructurationDestructuration
24 ✗ ✗
With arrayWith array// Assignmentvar [day, month, year] = [19, 02, 2014];
// Swap two values.var x=3, y=4;[x, y] = [y, x];
Array with functionsArray with functionsvar now = function() { return [19, 02, 2014]; }var [day, month] = now();var [, , year] = now();
With objectsWith objectsvar now = function() { return { d: 19, m: 2, y: 2014}}
var {d: day, m: month} = now();// day: 19// month: 2
As argument of a functionAs argument of a functionrecipes = [ { name: 'burger', calorie: 215 }, { name: 'pizza', calorie: 266 } ];
recipes.forEach(function ({ name: name, calorie: calorie }) { console.log(name, calorie); });
Default function parametersDefault function parameters
24 30 ✗
Ability to define default value for functionsAbility to define default value for functionsparamaters.paramaters.
No more:
function(a) { if(!a) { a = 10; } // do stuff with a}
NowNowfunction(a=10) { // do stuff with a}
Undefined and nullUndefined and nullundefined 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
ArityArityNumber of parameters without default value
(function(a){}).length // 1(function(a=10){}).length // 0(function(a=10, b){}).length // 1
Rest parametersRest parameters
24 ✗ ✗
Better than Better than argumentsargumentsfunction(name) { console.log(name); arguments[0] = 'ME !'; console.log(name); // ME ! Array.isArray(arguments); // false}
NowNowfunction(...args) { Array.isArray(args); // true // do some stuff}
function(name, ...more) {
}
ExampleExamplevar 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
RestrictionsRestrictionsRest parameters can only be the last parameter
// incorrectfunction(...args, callback) {}
DetailsDetailsRest parameter is always an array
function f(name, ...more) { Array.isArray(more); // always true return more.length;}f(); // returns 0
ArityArityDoes not include the rest parameter
(function(a) {}).length // 1(function(a, ...rest) {}).length // 1
SpreadSpread
24 (with array) 27-28 (with functions)
✗ ✗
Expand expression where multipleExpand expression where multiplearguments or multiple element are neededarguments or multiple element are needed
More powerful arrayMore powerful arraymanipulationmanipulation
Usecase: create new array with an existing one inside it:
var from = [1, 2];// wants: [0, 1, 2, 3] ie [0, from, 3]
With es5With es5a.unshift(0);a.push(3);// and splice is here also
With es6With es6var total = [0, ...from, 3];
Converting any array-likeConverting any array-like
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 wildArray like in the wildFunction's argumentsAll nodeList from the DOM
Before:
var nodes = document.querySelectorAll('p');var nodes = [].slice.call(nodes);
And now:
nodes = [...nodes];
Array conversionArray conversionBetter way:
Array.from(document.querySelectorAll('p'));
Out of the scope of the talk.
Spread with functionsSpread with functionsA better A better applyapply
var f = function(one, two, three) {}var a = [1, 2, 3];f.apply(null, a);
Apply ?Apply ?Function.prototype.applyfun.apply(thisArg, [argsArray])
Apply exampleApply examplefunction 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 spreadWith es6's spreadvar f = function(one, two, three) {}var a = [1, 2, 3];f(...a);
Sweet syntaxSweet syntaxvar f = function(a, b, c, d, e, f) {};var a = [1, 2];f(-1, ...a, 3, ...[-3, -4]);
Apply for Apply for newnewWith 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 pushBetter pushTo push multiple elements:
var a = [];var toPush = [1, 2, 3];a.push.apply(a, toPush);
And now:
a.push(...toPush);
Next...Next...
IteratorsIterators
24 ✗ ✗
An iterator lets you iterate over the contents of an object.
In ES6, an iterator is an object with a next() method whichreturns {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()); // {done: false, value: 1}console.log(i.next()); // {done: false, value: 2}console.log(i.next()); // {done: false, value: 3}console.log(i.next()); // {done: 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}
GeneratorsGenerators
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 asynchronousprogramming!
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...');}
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...
{ done: true, value: undefined
}
The code in the generator doesn't start executing until you sayso.
When the yield statement is encountered it suspendsexecution 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 handlethe 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.
- similar torunGenerator but more powerful.
- kick-assPromise library and provides runGenerator-like methods.
https://github.com/visionmedia/co
https://github.com/petkaantonov/bluebird
Generator delegation:
var inner = function*() { try { yield callServer1(); yield callServer2(); } catch (e) { console.error(e); }};
var outer = function*() { yield* inner();};
runGenerator(outer);
var outer = function*() { try { yield callServer1(); yield callServer2(); } catch (e) { console.error(e); }};
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-to-promises.html
Next...Next...
CollectionsCollections
24 30 11
SetSet - no duplicates allowed - no duplicates allowedvar 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) ); // trueconsole.log( items.has(5) ); // false
items.delete(4);console.log( items.has(4) ); // falseconsole.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); ) // trueconsole.log( map.get(23) ); // "age"console.log( map.size ); // 2
Map vs Object
Maps can have non-string keysMaps don't have prototype leakage issues, i.e. no need touse 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 Mapvar 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...Next...
Typed objectsTyped objects
✗ ✗ ✗
Typed objects are similar to struct objects in C
They provide memory-safe, structured access to contiguousdata
They can expose a binary representation, makingserialization/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 copiedc.point.x = 5;p.x; // 1
Built-in value types
uint8, uint8Clampeduint16uint32int8int16int32float32float64booleanstring
Next...Next...
Direct proxiesDirect proxies
24 ✗ ✗
Direct proxies allows you to intercept calls made to a regularobject
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...Next...
Template stringsTemplate 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']// 60var 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...Next...
API improvementsAPI 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...Next...
ModularityModularity
✗ ✗ ✗
ClassesClasses
In es5In es5Classes doesn't exist nativelyPrototype based inheritanceFramework and libraries implement their own class system
New keywordNew keywordclass Laptop { constructor() { this.brand = 'asus'; }
on() { ... } off() { ... }}
Call the parentCall the parentclass SmashedLaptop extend Laptop { constructor() { super(); this.pieces = []; }}
Key pointsKey pointsconstructor replace the function definition in es5No access to the prototype of the classMethods are defined the same way as objectsCan call the parent with super (and perform initializationwithin the constructor)
ModulesModules• import the default export of a moduleimport $ from "jquery";
• binding an external module to a variablemodule crypto from "crypto";
• binding a module's exports to variablesimport { encrypt, decrypt } from "crypto";
ModulesModules• binding & renaming one of a module's exportsimport { encrypt as enc } from "crypto";
• re-exporting another module's exportsexport * from "crypto";
• re-exporting specified exportsfrom another moduleexport { foo, bar } from "crypto";
Why ?Why ?No need for the global object anymoreWorks well with existing modules system (AMD,CommonJS and node)Simplicity and usabilityCompatibility with browser and non-browser environmentsEasy asynchronous external loading
Exporting and importingExporting and importingmodule "chocolate" { export let cocoa = 75;}
In another file:
import { cocoa } from "chocolate";// orimport { cocoa as c} from "chocolate";
Default exportDefault exportmodule "foo" {
export default function() {console.log("Hi")}
}
import foo from "foo"; // no brackets
foo(); // Hi
InternalsInternalsTop-level variables stay inside the moduleexport 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 evaluationModules' body is run after all dependencies are instantiated
That's all forThat's all fortoday!today!
See for morehttp://kangax.github.io/es5-compat-table/es6/
Useful linksUseful linkshttp://www.ecmascript.org/http://www.esdiscuss.org/https://developer.mozilla.org/en/docs/Web/JavaScript/ECMAScript_6_support_in_Mozilla