Slide 1

Slide 1 text

ECMAScript 6: highlights and recommendations Front-Trends, 2015-05-06 Slides: speakerdeck.com/rauschma

Slide 2

Slide 2 text

Dr. Axel Rauschmayer, Ecmanauten.de ECMAScript 6 (ES6): JavaScript, improved ECMAScript 6: next version of JavaScript (current: ES5). This presentation: • Overview of ES6 • Assessment of ES6 features • Cool stuff you can do with ES6 2

Slide 3

Slide 3 text

Background

Slide 4

Slide 4 text

Dr. Axel Rauschmayer, Ecmanauten.de Important ES terms • TC39 (Ecma Technical Committee 39): the committee evolving JavaScript • ECMAScript: official name of the language • Versions: ECMAScript 5 is short for “ECMAScript Language Specification, Edition 5” • ECMAScript 2015: new official name for ES6 (in preparation for yearly releases in ES7+) • Complicated, because ES6 is already so established • JavaScript: the language, colloquially • ECMAScript Harmony: set of features after ES5 (ES6 and later) 4

Slide 5

Slide 5 text

Dr. Axel Rauschmayer, Ecmanauten.de Time table ECMAScript 6 is done: • The spec is frozen • June 2015: formal publication • Features are continually appearing in current engines. 5

Slide 6

Slide 6 text

Assessing ES6 features

Slide 7

Slide 7 text

Dr. Axel Rauschmayer, Ecmanauten.de Classes class Person { constructor(name) { this.name = name; } describe() { return 'Person called '+this.name; } } function Person(name) { this.name = name; } Person.prototype.describe = function () { return 'Person called '+this.name; }; 7

Slide 8

Slide 8 text

Dr. Axel Rauschmayer, Ecmanauten.de Why I recommend classes Pros: • Code more portable • Tool support (IDEs, type checkers, …) • Foundation for (longer term): • immutable objects • value objects • traits (similar to mixins) • Subclassing built-ins • Help many newcomers
 Cons: • Syntax quite different from semantics • Based on constructors, not prototype chains (directly) 8

Slide 9

Slide 9 text

Dr. Axel Rauschmayer, Ecmanauten.de ES6 features: the good Good and boring: • Polyfillable parts of standard library (Maps, new String +Array methods, Promises) • Unify community, convenient syntax: • Modules • Classes • Arrow functions: less clutter, lexical this 9

Slide 10

Slide 10 text

Dr. Axel Rauschmayer, Ecmanauten.de ES6 features: the good • Generators: lazy programming and cooperative multitasking • Proxies: meta-programming (shimming the DOM etc.) • WeakMaps: caching, private data • Destructuring: handling return values, parameters, for-of loop elements 10

Slide 11

Slide 11 text

Dr. Axel Rauschmayer, Ecmanauten.de ES6 features: the bad • Enumerability more complicated than ever • Coercion rules for symbols are complicated, probably not worth their benefits • Disconnect between class syntax and class semantics (look like an object, are a function) • Kind-of work-around: treat them at face value 11

Slide 12

Slide 12 text

Dr. Axel Rauschmayer, Ecmanauten.de ES6 features: the OK • Symbols 12

Slide 13

Slide 13 text

Various cool features

Slide 14

Slide 14 text

Dr. Axel Rauschmayer, Ecmanauten.de Destructuring Extract multiple values via patterns: let obj = { first: 'Jane', last: 'Doe' }; let { first: f, last: l } = obj; // f='Jane', l='Doe' Can be used for: • variable declarations (var, let, const) • assignments • parameter definitions • for-of loop 14

Slide 15

Slide 15 text

Dr. Axel Rauschmayer, Ecmanauten.de Destructuring: arrays let [x, y] = ['a', 'b']; // x='a', y='b' let [x, y, ...rest] = ['a', 'b', 'c', 'd']; // x='a', y='b', rest = [ 'c', 'd' ] [x,y] = [y,x]; // swap values let [all, year, month, day] = /^(\d\d\d\d)-(\d\d)-(\d\d)$/ .exec('2999-12-31'); 15

Slide 16

Slide 16 text

Dr. Axel Rauschmayer, Ecmanauten.de Named parameters // Emulated via object literals and destructuring // { opt1, opt2 } is same as // { opt1: opt1, opt2: opt2 } selectEntries({ step: 2 }); selectEntries({ end: 20, start: 3 }); selectEntries(); // enabled via `= {}` below function selectEntries( {start=0, end=-1, step=1} = {}) { ··· }; 16

Slide 17

Slide 17 text

Dr. Axel Rauschmayer, Ecmanauten.de Template literals // String interpolation if (x > MAX) { throw new Error( `At most ${MAX} allowed: ${x}!` // 'At most '+MAX+' allowed: '+x+'!' ); } // Multiple lines let str = `this is a text with multiple lines`; 17

Slide 18

Slide 18 text

Dr. Axel Rauschmayer, Ecmanauten.de WeakMaps • Maps with arbitrary keys, arbitrary values • Key garbage collected 㱺 entry garbage collected • Thus: great for attaching data to objects 18

Slide 19

Slide 19 text

Dr. Axel Rauschmayer, Ecmanauten.de WeakMaps for private data let _counter = new WeakMap(); let _action = new WeakMap(); class Countdown { constructor(counter, action) { _counter.set(this, counter); _action.set(this, action); } dec() { let counter = _counter.get(this); if (counter < 1) return; counter--; _counter.set(this, counter); if (counter === 0) { _action.get(this)(); } } } 19

Slide 20

Slide 20 text

Cool features: generators

Slide 21

Slide 21 text

Dr. Axel Rauschmayer, Ecmanauten.de Generators as data consumers function* dataConsumer() { console.log('Started'); console.log(`1. ${yield}`); console.log(`2. ${yield}`); return 'result'; } > let genObj = dataConsumer(); > genObj.next() // progress to next suspension Started { value: undefined, done: false } > genObj.next('a') 1. a { value: undefined, done: false } > genObj.next('b') 2. b { value: 'result', done: true } 21

Slide 22

Slide 22 text

Dr. Axel Rauschmayer, Ecmanauten.de Async lazy processing: start let fileName = process.argv[2]; readFile(fileName, chain(splitLines, numberLines, printLines)); 22

Slide 23

Slide 23 text

Dr. Axel Rauschmayer, Ecmanauten.de Step 1: pushing data asynchronously /** * Create asynchronous ReadStream for file `fileName` * and feed it to generator object `target`. */ function readFile(fileName, target) { let readStream = createReadStream(fileName, { encoding: 'utf8', bufferSize: 1024 }); readStream.on('data', buffer => { let str = buffer.toString('utf8'); target.next(str); }); readStream.on('end', () => { // Signal end of output sequence target.return(); }); } 23

Slide 24

Slide 24 text

Dr. Axel Rauschmayer, Ecmanauten.de Step 2: text chunks → sequence of lines function* splitLines(target) { let previous = ''; try { while (true) { previous += yield; let eolIndex; while ((eolIndex = previous.indexOf('\n')) >= 0) { let line = previous.slice(0, eolIndex); target.next(line); previous = previous.slice(eolIndex+1); } } } finally { // Handle the end of the input sequence // (signaled via `return()`) if (previous.length > 0) { target.next(previous); } // Signal end of output sequence target.return(); } } 24

Slide 25

Slide 25 text

Dr. Axel Rauschmayer, Ecmanauten.de Step 3: prefix numbers to a sequence of lines function* numberLines(target) { try { for (let lineNo = 0; ; lineNo++) { let line = yield; target.next(`${lineNo}: ${line}`); } } finally { // Signal end of output sequence target.return(); } } 25

Slide 26

Slide 26 text

Dr. Axel Rauschmayer, Ecmanauten.de Step 4: log result function* printLines() { while (true) { let line = yield; console.log(line); } } Everything happens on demand, text chunk by text chunk! 26

Slide 27

Slide 27 text

Cool features: generators as data producers

Slide 28

Slide 28 text

Dr. Axel Rauschmayer, Ecmanauten.de Generators as data producers function* genFunc() { yield 'a'; yield 'b'; } > let genObj = genFunc(); > genObj.next() { value: 'a', done: false } > genObj.next() { value: 'b', done: false } > genObj.next() // end of sequence reached { value: undefined, done: true } 28

Slide 29

Slide 29 text

Dr. Axel Rauschmayer, Ecmanauten.de An iterator for a tree (1/2) class BinaryTree { constructor(value, left=null, right=null) { this.value = value; this.left = left; this.right = right; } /** Prefix iteration */ * [Symbol.iterator]() { yield this.value; if (this.left) { yield* this.left; } if (this.right) { yield* this.right; } } } 29

Slide 30

Slide 30 text

Dr. Axel Rauschmayer, Ecmanauten.de An iterator for a tree (2/2) let tree = new BinaryTree('a', new BinaryTree('b', new BinaryTree('c'), new BinaryTree('d')), new BinaryTree('e')); for (let x of tree) { console.log(x); } // Output: // a // b // c // d // e 30

Slide 31

Slide 31 text

Cool features: generators for async

Slide 32

Slide 32 text

Dr. Axel Rauschmayer, Ecmanauten.de Asynchronous programming (1/2) co(function* () { try { let [croftStr, bondStr] = yield Promise.all([ getFile('http://localhost:8000/croft.json'), getFile('http://localhost:8000/bond.json'), ]); let croftJson = JSON.parse(croftStr); let bondJson = JSON.parse(bondStr); console.log(croftJson); console.log(bondJson); } catch (e) { console.log('Failure to read: ' + e); } }); 32

Slide 33

Slide 33 text

Dr. Axel Rauschmayer, Ecmanauten.de Asynchronous programming (2/2) function getFile(url) { return fetch(url) .then(request => request.text()); } 33

Slide 34

Slide 34 text

Conclusion

Slide 35

Slide 35 text

Dr. Axel Rauschmayer, Ecmanauten.de Take-aways: ECMAScript 6 • Many features are already in engines • Can be used today, by compiling to ECMAScript 5 • Biggest impact on community (currently: fragmented): • Classes • Modules 35

Slide 36

Slide 36 text

Thank you! • Free online book by Axel: “Exploring ES6” • GitHub: rauschma/generator-examples/node/readlines.js © Scott the Hobo