Slide 1

Slide 1 text

ECMAScript 6: The Re ned Parts Kit Cambridge

Slide 2

Slide 2 text

Every technology has a story. The story provides the context for the nal product. Without a story, few decisions make sense.

Slide 3

Slide 3 text

1995 1999 2005 2009 2013

Slide 4

Slide 4 text

1995 1999 2005 2009 2013 Function expressions Regular expressions throw Array literals Object literals String, number, date methods try...catch switch instanceof in do...while ===

Slide 5

Slide 5 text

1995 1999 2005 2009 2013 Interfaces Pragmas Classes Namespaces Static type system goto ...rest Packages Lexical binding Block scope Generators Overloading Iterators Type annotations Strict mode Re ection

Slide 6

Slide 6 text

1995 1999 2005 2009 2013 Tighter regular expression, eval, error, and global object semantics Standardizing de facto behaviors Array extras New object re ection methods Strict mode Native JSON support get() set(value)

Slide 7

Slide 7 text

1995 1999 2005 2009 2013 Classes Template Literals Object Shorthands Proxies Modules Block Scope Destructuring Unicode Binary Data Collections Arrow Functions Symbols Generators Iterators Tail-Call Optimization ...rest ...spread Default parameters for...of Re ection Convenience methods

Slide 8

Slide 8 text

“To ES 7...and beyond!” 1995 1999 2005 2009 2013

Slide 9

Slide 9 text

Generators Suspend and resume execution at multiple locations .next(value) resumes execution yield suspends execution .throw(error) raises an exception at the suspended location

Slide 10

Slide 10 text

function* fibonacci() { var [previous, current] = [0, 1]; while (1) { [previous, current] = [current, previous + current]; let isReset = yield current; if (isReset) { [previous, current] = [0, 1]; } } } function* distinguishes a generator from a function yield returns a generator object that can modify the generator’s state

Slide 11

Slide 11 text

var generator = fibonacci(); generator.next(); // => { value: 1, done: false } generator.next(); // => { value: 2, done: false } generator.next(true); // => { value: 1, done: false } generator.throw(Error('Exceptional condition.')); // => Throws an error with the given message.

Slide 12

Slide 12 text

What if the caller of .next() and .throw() could resume execution when an asynchronous operation completed? github.com/kriskowal/q github.com/visionmedia/co

Slide 13

Slide 13 text

var {name, address} = request.payload; Q.async(function* createAccount() { let account = null; try { account = yield Account.getByAddress(address); } catch (exception) { if (exception.response.code != 404) { throw exception; } } if (account) { throw new Error('This address is already in use.'); } account = new Account(); account.update({ name, address }); yield account.save(); });

Slide 14

Slide 14 text

Collections Map Set WeakMap WeakSet

Slide 15

Slide 15 text

Collections All collections support sub-linear lookup times Sets can remove duplicates in linear time Maps and Sets enumerate entries in insertion order WeakMaps and WeakSets use weak references to allow for garbage collection var unique = [...new Set([1, 2, O, 2, 3, 'A', 'B', O, 'C', 'C', 'D'])]; // => [1, 2, O, 3, 'A', 'B', 'C', 'D']

Slide 16

Slide 16 text

// Leak-free element storage engine. var storage = new WeakMap(); function store(element, name, value) { // Create the element data store if // it doesn't exist. if (!storage.has(element)) { storage.set(element, new Map()); } // Associate the name and value with // the element. storage.get(element).set(name, value); return element; }

Slide 17

Slide 17 text

function retrieve(element, name) { if (!storage.has(element)) { return; } return storage.get(element).get(name); } function unstore(element, name) { if (!storage.has(element)) { return; } let data = storage.get(element); let value = data.get(name); data.delete(name); return value; }

Slide 18

Slide 18 text

Symbols Unique, private object property names A memory-e cient alternative to the revealing module pattern [] distinguishes between symbols and strings

Slide 19

Slide 19 text

let uri = Symbol(), clientId = Symbol(); let clientSecret = Symbol(); function OAuthClient(baseURI, id, secret) { this[uri] = baseURI; this[clientId] = id; this[clientSecret] = secret; } OAuthClient.prototype = { request(endpoint, credentials) { let id = this[clientId]; let secret = this[clientSecret]; return new Request(this[uri], endpoint). sign({ id, secret }, credentials); } };

Slide 20

Slide 20 text

Destructuring Assignment Pull values from objects and arrays Swap variables Parse complex structures in a single statement Specify default values for arguments

Slide 21

Slide 21 text

var {parse, stringify} = JSON; const pattern = /^(?:(\d{3})-)?(\d{3}-\d{4})$/; var [, areaCode = 415, local] = pattern.exec(phone); [left, right] = [right, left]; let getHeaders = ({'request': {headers}}) => headers

Slide 22

Slide 22 text

var poets = [{ "name": "T.S. Eliot", "works": [{ "title": "The Love Song of J. Alfred Prufrock", "date": 1915 }, { "title": "Rhapsody on a Windy Night", "date": 1917 }] }, { "name": "Ezra Pound", "works": [{ "title": "Ripostes", "date": 1912 }] }]; var [{'name': author, 'works': [, {title, date}]}] = poets; `"${title}", by ${author}, was published in ${date}.` // => '"Rhapsody on a Windy Night", by T.S. Eliot, was published in 1917.'

Slide 23

Slide 23 text

function request(uri = '', { method = 'GET', qs = {}, headers = {}, body, form, auth, json, maxRedirects = 10, jar = false }) { // ... } Default parameter syntax Destructuring with default values

Slide 24

Slide 24 text

Shorthand Syntax Initializers Method De nitions var name = 'Kit'; var occupation = 'programmer'; var person = { 'name': name, 'occupation': occupation }; var name = 'Kit'; var occupation = 'programmer'; var person = { name, occupation };

Slide 25

Slide 25 text

Shorthand Method Template Literal Getter New API Method var years = Symbol(); function Speaker(name) { this.name = name; this[years] = 0; } Speaker.prototype = { speak(message) { return `${this.name}: ${message}`; }, get age() { return this[years]; }, set age(value) { if (Number.isFinite(value)) { this[years] = value; } } }

Slide 26

Slide 26 text

...spread Expand an array of arguments without altering this Supports constructors Convenient syntax for merging arrays and array-like objects Convert any object with a length property into an array

Slide 27

Slide 27 text

...rest Supplants the arguments object Always returns an array, even when parameters are omitted Natural syntax for variadic functions Only valid as the last parameter of a function

Slide 28

Slide 28 text

function getCredentials({ 'request': { 'headers': { authorization } } }) { let [scheme , ...components] = authorization.split(' '); if (scheme != 'Basic' || components.length > 1) { return null; } let [credentials] = components; credentials = new Buffer(credentials, 'base64').toString('utf8'); if (!credentials.contains(':')) { return null; } let pattern = /^([^:]+):(\w+)$/; let [, name = '', password = ''] = pattern.exec(credentials) || []; return { name, password }; } getCredentials(request); // => { name: 'Kit', password: '...' }

Slide 29

Slide 29 text

Tagged Template Literals `-delimited, multiline strings with embedded expressions Handlers may perform additional processing Contextual escaping Build extensible template languages

Slide 30

Slide 30 text

function escape(values, ...substitutions) { let { raw, 'raw': { length } } = values; let results = ''; for (let index = 0; index < length; index++) { results += raw[index]; if (index + 1 == length) { break; } results += String(substitutions[index]).replace(/[&<>"']/g, (match) => `${match.codePointAt(0).toString(16)};`); } return results; } let name = 'Kitalert(1)'; escape`${name}`; // => 'Kit<script>alert(1)</ script>'

Slide 31

Slide 31 text

Block Scope Lexical declarations with let and const let introduces meaningful semantics for blocks Function declarations are now supported within blocks const declarations may not be reassigned

Slide 32

Slide 32 text

// The problem. for (var length = 2; length--;) { var dimension = length ? 'Width' : 'Height'; // Both methods will report the element's height. $['get' + dimension] = function getDimension(element) { return element['offset' + dimension]; }; } // The ES 6 solution. for (var length = 2; length--;) { let dimension = length ? 'Width' : 'Height'; $['get' + dimension] = function getDimension(element) { return element['offset' + dimension]; } }

Slide 33

Slide 33 text

Gotchas

Slide 34

Slide 34 text

function getMood({ 'actions': { isSinging } }) { // Syntax error. Lexical declarations must be nested // within blocks. if (isSinging) let mood = 'greatlyImproved'; // Syntax error. Constants cannot be re-declared. const isWritingCode = true; const isWritingCode = false; // Type error in strict mode. Constants are read-only. isWritingCode = false; // Syntax error. `var` declarations cannot shadow // `let` and `const` declarations. var isWritingCode = true; }

Slide 35

Slide 35 text

=> Functions Parentheses not required for single-parameter functions Blocks not required for single-value expressions Runtime semantics identical to bound functions [1, 2, 3, 4, 5].filter(value => value % 2); // => [1, 3, 5] let identify = (() => ({ 'toString': () => { return 'Kit'; } }); `${identify()} <3s ES 6.`; // => 'Kit <3s ES 6.'

Slide 36

Slide 36 text

Something for everyone. Shorthand Syntax Data Structures Modularity Core Re nements Tooling

Slide 37

Slide 37 text

When can I use...? kangax.github.com/es5-compat-table/es6 “Enable Experimental JavaScript” in about: ags Some non- standard features --harmony ag

Slide 38

Slide 38 text

Continuum Traceur es6ify benvie.github.com/ continuum github.com/google/ traceur-compiler github.com/thlorenz/ es6ify

Slide 39

Slide 39 text

Follow @esdiscuss Catch up at esdiscuss.org

Slide 40

Slide 40 text

Thank you! @kitcambridge Black Pearl Systems