Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ECMAScript 6 in theory and practice

ECMAScript 6 in theory and practice

Avatar for Axel Rauschmayer

Axel Rauschmayer

April 20, 2015
Tweet

More Decks by Axel Rauschmayer

Other Decks in Programming

Transcript

  1. Dr. Axel Rauschmayer, Ecmanauten.de JavaScript is everywhere • In browsers

    (big apps), servers, devices, robots, … • Does much more than what it was originally created for. • How can we help it with that? 2 © Schmeegan
  2. Axel @rauschma Frosty @js_dev #FluentConf ECMAScript 6 (ES6): JavaScript, improved

    ECMAScript 6: next version of JavaScript (current: ES5). This presentation: • Background (terms, goals, design process) • Using ES6 today • Features 3
  3. Axel @rauschma Frosty @js_dev #FluentConf Important ES terms • TC39

    (Ecma Technical Committee 39): the committee evolving JavaScript • Members: companies (all major browser vendors etc.) • Meetings attended by employees and invited experts • ECMAScript: the 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: • colloquially: the language • formally: one implementation of ECMAScript • ECMAScript Harmony: improvements after ECMAScript 5 (ECMAScript 6 and later) 5
  4. Axel @rauschma Frosty @js_dev #FluentConf Goals for ECMAScript 6 Amongst

    other official goals: make JavaScript better • for complex applications • for libraries (including the DOM) • as a target of code generators 6
  5. Axel @rauschma Frosty @js_dev #FluentConf How to upgrade a web

    language? Challenges w.r.t. upgrading: • JavaScript engines: • New versions = forced upgrades • Must run all existing code 㱺 ECMAScript 6 is a superset of ES5 (nothing is removed) • JavaScript code: • Must run on all engines that are in use 㱺 wait or compile ECMAScript 6 to ES5 (details later). 7
  6. Axel @rauschma Frosty @js_dev #FluentConf Goals and requirements 8 Don’t

    break existing code Add new features Fix pitfalls Preserve nature of JavaScript Goals Requirements
  7. Axel @rauschma Frosty @js_dev #FluentConf How ECMAScript features are designed

    Avoid “design by committee”: • Design by “champions” (1–2 experts) • Feedback from TC39 and web development community • Field-testing and refining via one or more implementations • TC39 has final word on whether/when to include ES7+: smaller, yearly scheduled releases 9
  8. Axel @rauschma Frosty @js_dev #FluentConf Overview of features Better syntax

    for existing features. E.g.: • Classes • Modules Better standard library. E.g.: • New methods for strings, arrays • Promises • Maps, Sets
 Completely new features. E.g.: • Generators • Proxies • WeakMaps 10
  9. Axel @rauschma Frosty @js_dev #FluentConf Time table ECMAScript 6 is

    done: • The spec is frozen • June 2015: formal publication • Features are continually appearing in current engines. 12
  10. Axel @rauschma Frosty @js_dev #FluentConf ES6 tools Transpiler (your code):

    • TypeScript • Traceur • Babel Package manager (libraries): • npm • Bower • jspm
 Module system (complete app): • RequireJS • Browserify • webpack • SystemJS
 Linter (your code): • JSLint • JSHint • ESLint • JSCS Shims (for ES5): • Core.js • es6-shim 13
  11. Axel @rauschma Frosty @js_dev #FluentConf Traceur and Babel Run... •

    Statically (at development time): use build tools (Grunt, Gulp, Broccoli, etc.) to generate modules. E.g.: • AMD (RequireJS) • CommonJS (Node.js, Browserify, etc.) • Dynamically (at runtime): library plus <script type="..."> 14
  12. Axel @rauschma Frosty @js_dev #FluentConf Block-scoped variables // Function scope

    (var) function order(x, y) { if (x > y) { var tmp = x; x = y; y = tmp; } console.log(tmp===x); // true return [x, y]; }
 // Block scope (let,const) function order(x, y) { if (x > y) { let tmp = x; x = y; y = tmp; } console.log(tmp===x); // ReferenceError: // tmp is not defined return [x, y]; } 16
  13. Axel @rauschma Frosty @js_dev #FluentConf Constructing vs. extracting Construct //

    Single values let jane = {}; jane.first = 'Jane'; jane.last = 'Doe'; // Multiple values let jane = { first: 'Jane', last: 'Doe' };
 Extract // Single values let f = jane.first; let l = jane.last; // Multiple values let ??? = jane; 18
  14. Axel @rauschma Frosty @js_dev #FluentConf 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 19
  15. Axel @rauschma Frosty @js_dev #FluentConf 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'); 20
  16. Axel @rauschma Frosty @js_dev #FluentConf Multiple return values function findElement(arr,

    predicate) { for (let index=0; index < arr.length; index++) { let element = arr[index]; if (predicate(element)) { return { element, index }; // same as { element: element, index: index } } } return { element: undefined, index: -1 }; } let a = [7, 8, 6]; let {element, index} = findElement(a, x => x % 2 === 0); // element = 8, index = 1 let {index, element} = findElement(···); // order doesn't matter let {element} = findElement(···); let {index} = findElement(···); 21
  17. Axel @rauschma Frosty @js_dev #FluentConf Modules: named exports // lib/math.js

    let notExported = 'abc'; export function square(x) { return x * x; } export const MY_CONSTANT = 123; // main1.js import {square} from 'lib/math'; console.log(square(3)); // main2.js import * as math from 'lib/math'; console.log(math.square(3)); 23
  18. Axel @rauschma Frosty @js_dev #FluentConf Modules: default exports //----- myFunc.js

    ----- export default function (...) { ... } //----- main1.js ----- import myFunc from 'myFunc'; //----- MyClass.js ----- export default class { ... } //----- main2.js ----- import MyClass from 'MyClass'; 24
  19. Axel @rauschma Frosty @js_dev #FluentConf Method definitions let obj =

    { myMethod() { ··· } }; // Equivalent: var obj = { myMethod: function () { ··· } }; 27
  20. Axel @rauschma Frosty @js_dev #FluentConf Property value shorthands let x

    = 4; let y = 1; let obj = { x, y }; // Same as { x: x, y: y } 28
  21. Axel @rauschma Frosty @js_dev #FluentConf Computed property keys (1/2) let

    propKey = 'hello'; let obj = { ['fo'+'o']: 123, [propKey]() { return 'hi'; }, }; console.log(obj.hello()); // hi 29
  22. Axel @rauschma Frosty @js_dev #FluentConf Computed property keys (2/2) let

    obj = { // Key is a symbol [Symbol.iterator]() { ··· } }; for (let x of obj) { console.log(x); } 30
  23. Axel @rauschma Frosty @js_dev #FluentConf Parameter default values Use a

    default if a parameter is missing. function func1(x, y='default') { return [x,y]; } Interaction: > func1(1, 2) [1, 2] > func1() [undefined, 'default'] 32
  24. Axel @rauschma Frosty @js_dev #FluentConf Rest parameters Put trailing parameters

    in an array. function func2(arg0, ...others) { return others; } Interaction: > func2('a', 'b', 'c') ['b', 'c'] > func2() [] No need for arguments, anymore. 33
  25. Axel @rauschma Frosty @js_dev #FluentConf No needs for arguments //

    ES5 function func() { [].forEach.call(arguments, function (x) {···}); ··· } // ES6 function func(...args) { for (let arg of args) { ··· } } 34
  26. Axel @rauschma Frosty @js_dev #FluentConf 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} = {}) { ··· }; 35
  27. Axel @rauschma Frosty @js_dev #FluentConf Spread operator (...): function arguments

    Math.max(...[7, 4, 11]); // 11 let arr1 = ['a', 'b']; let arr2 = ['c', 'd']; arr1.push(...arr2); // arr1 is now ['a', 'b', 'c', 'd'] // Also works in constructors! new Date(...[1912, 11, 24]) // Christmas Eve 1912 Turn an array into function/method arguments: • The inverse of rest parameters • Mostly replaces Function.prototype.apply() 36
  28. Axel @rauschma Frosty @js_dev #FluentConf Spread operator (...): array elements

    let a = [1, ...[2,3], 4]; // [1, 2, 3, 4] // Concatenate arrays let x = ['a', 'b']; let y = ['c']; let z = ['d', 'e']; let xyz = [...x, ...y, ...z]; // ['a', 'b', 'c', 'd', 'e'] // Convert iterable objects to arrays let set = new Set([11, -1, 6]); let arr = [...set]; // [11, -1, 6] 37
  29. Axel @rauschma Frosty @js_dev #FluentConf Arrow functions: less to type

    let arr = [1, 2, 3]; let squ; squ = arr.map(function (a) {return a * a}); squ = arr.map(a => a * a); 39
  30. Axel @rauschma Frosty @js_dev #FluentConf Arrow functions: lexical this, no

    more that=this function UiComponent { var that = this; var button = document.getElementById('myButton'); button.addEventListener('click', function () { console.log('CLICK'); that.handleClick(); }); } UiComponent.prototype.handleClick = function () { ... }; function UiComponent { let button = document.getElementById('myButton'); button.addEventListener('click', () => { console.log('CLICK'); this.handleClick(); }); } 40
  31. Axel @rauschma Frosty @js_dev #FluentConf Arrow functions: versions (arg1, arg2,

    ···) => expr (arg1, arg2, ···) => { stmt1; stmt2; ··· } singleArg => expr singleArg => { stmt1; stmt2; ··· } 41
  32. Axel @rauschma Frosty @js_dev #FluentConf 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; }; 44
  33. Axel @rauschma Frosty @js_dev #FluentConf Subclassing class Employee extends Person

    { constructor(name, title) { super(name); this.title = title; } describe() { return super.describe() + ' (' + this.title + ')'; } } function Employee(name, title) { Person.call(this, name); this.title = title; } Employee.prototype = Object.create(Person.prototype); Employee.prototype.constructor = Employee; Employee.prototype.describe = function () { return Person.prototype.describe.call(this) + ' (' + this.title + ')'; }; 45
  34. Axel @rauschma Frosty @js_dev #FluentConf 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 some newcomers
 Cons: • Syntax quite different from semantics • Based on constructors, not prototype chains (directly) 46
  35. Axel @rauschma Frosty @js_dev #FluentConf 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`; 48
  36. Axel @rauschma Frosty @js_dev #FluentConf Tagged templates = function calls

    Usage: tagFunction`Hello ${first} ${last}!` Syntactic sugar for: tagFunction(['Hello ', ' ', '!'], first, last) Two kinds of tokens: • Template strings (static): 'Hello ' • Substitutions (dynamic): first 49
  37. Axel @rauschma Frosty @js_dev #FluentConf Template literals/tagged templates vs. templates

    Different (despite names and appearances being similar): • Web templates (data): HTML with blanks to be filled in • Template literals (code): multi-line string literals plus interpolation • Tagged templates (code): function calls 50
  38. Axel @rauschma Frosty @js_dev #FluentConf Tagged templates: XRegExp XRegExp library:

    ignored whitespace, named groups, comments // ECMAScript 5 var str = '/2012/10/Page.html'; var parts = str.match(XRegExp( '^ # match at start of string only \n' + '/ (?<year> [^/]+ ) # capture top dir as year \n' + '/ (?<month> [^/]+ ) # capture subdir as month \n' + '/ (?<title> [^/]+ ) # file name base \n' + '\\.html? # file name extension: .htm or .html \n' + '$ # end of string', 'x' )); Problems: • Escaping: backslash of string literals vs. backslash of regular expression • One string literal per line 51
  39. Axel @rauschma Frosty @js_dev #FluentConf Tagged templates: XRegExp // ECMAScript

    6 let str = '/2012/10/Page.html'; let parts = str.match(XRegExp.rx` ^ # match at start of string only / (?<year> [^/]+ ) # capture top dir as year / (?<month> [^/]+ ) # capture subdir as month / (?<title> [^/]+ ) # file name base \.html? # file name extension: .htm or .html $ # end of string `); console.log(parts.year); // 2012 52
  40. Axel @rauschma Frosty @js_dev #FluentConf Tagged templates: other use cases

    Great for building embedded DSLs: • Query languages • Text localization • JSX • etc. 53
  41. Axel @rauschma Frosty @js_dev #FluentConf Maps Dictionaries from arbitrary values

    to arbitrary values. let map = new Map(); let obj = {}; map.set(obj, 123); console.log(map.get(obj)); // 123 console.log(map.has(obj)); // true map.delete(obj); console.log(map.has(obj)); // false for (let [key,value] of map) { console.log(key, value); } 55
  42. Axel @rauschma Frosty @js_dev #FluentConf Sets A collection of values

    without duplicates. let set = new Set(); set.add('hello'); console.log(set.has('hello')); // true console.log(set.has('world')); // false // Sets are iterable let unique = [...new Set([3,2,1,3,2,3])]; // [3,2,1] for (let elem of set) { console.log(elem); } 56
  43. Axel @rauschma Frosty @js_dev #FluentConf 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)(); } } } 57
  44. Axel @rauschma Frosty @js_dev #FluentConf Iterable data sources • Arrays

    • Strings • Maps • Sets • arguments • DOM data structures (work in progress) Not: plain objects 59
  45. Axel @rauschma Frosty @js_dev #FluentConf Iterating constructs • Destructuring via

    array pattern • for-of loop • Array.from() • Spread operator (...) in arrays and function calls • Constructor argument of Maps and Sets • Promise.all(), Promise.race() • yield* 60
  46. Axel @rauschma Frosty @js_dev #FluentConf for-of: a better loop Replaces:

    • for-in • Array.prototype.forEach() Works for: iterables • Convert array-like objects via Array.from(). 61
  47. Axel @rauschma Frosty @js_dev #FluentConf for-of loop: arrays let arr

    = ['hello', 'world']; for (let elem of arr) { console.log(elem); } // Output: // hello // world 62
  48. Axel @rauschma Frosty @js_dev #FluentConf for-of loop: arrays let arr

    = ['a', 'b', 'c']; for (let [index, elem] of arr.entries()) { console.log(`${index}. ${elem}`); } // Output // 0. a // 1. b // 2. c 63
  49. Axel @rauschma Frosty @js_dev #FluentConf for-of loop: other iterables let

    set = new Set(['hello', 'world']); for (let elem of set) { console.log(elem); } // Output: // hello // world 64
  50. Axel @rauschma Frosty @js_dev #FluentConf Symbols A new kind of

    primitive value – unique IDs: > let sym = Symbol(); > typeof sym 'symbol' 67
  51. Axel @rauschma Frosty @js_dev #FluentConf Symbols: enum-style values const COLOR_RED

    = Symbol(); const COLOR_ORANGE = Symbol(); ··· function getComplement(color) { switch (color) { case COLOR_RED: return COLOR_GREEN; case COLOR_ORANGE: return COLOR_BLUE; ··· default: throw new Exception('Unknown color: '+color); } } 68
  52. Axel @rauschma Frosty @js_dev #FluentConf Symbols: property keys let specialMethod

    = Symbol(); obj[specialMethod] = function (arg) { ... }; obj[specialMethod](123); 69
  53. Axel @rauschma Frosty @js_dev #FluentConf Symbols: property keys • Important

    advantage: No name clashes! • Separate levels of method keys:
 app vs. framework • Configure objects for ECMAScript and frameworks: • Introduce publicly known symbols. • Example: property key Symbol.iterator makes objects iterable. 70
  54. Dr. Axel Rauschmayer, Ecmanauten.de [Symbol.iterator]() ... Iterable: traversable data structure

    next() Iterator: pointer for traversing iterable returns Iterables and iterators Iteration protocol: • Iterable: a data structure whose elements can be traversed • Iterator: the pointer used for traversal Examples of iterables: • Arrays • Sets • arguments • All array-like DOM objects (eventually) 72
  55. Axel @rauschma Frosty @js_dev #FluentConf Iterables and iterators function iterateOver(...values)

    { let index = 0; let iterable = { [Symbol.iterator]() { let iterator = { next() { if (index < values.length) { return { value: values[index++] }; } else { return { done: true }; } } } return iterator; } } return iterable; } for (let x of iterateOver('eeny', 'meeny', 'miny')) { console.log(x); } 73
  56. Axel @rauschma Frosty @js_dev #FluentConf Generators // Suspend via `yield`

    (“resumable return”): function* generatorFunction() { yield 0; yield 1; yield 2; } // Start and resume via `next()`: let genObj = generatorFunction(); genObj.next(); // { value: 0, done: false } genObj.next(); // { value: 1, done: false } genObj.next(); // ( value: 2, done: false } genObj.next(); // ( value: undefined, done: true } 75
  57. Axel @rauschma Frosty @js_dev #FluentConf Generators: implementing an iterator function

    iterateOver(...vs) { let index = 0; let iterable = { [Symbol.iterator]() { let iterator = { next() { if (index < vs.length) { return {value: vs[index++]}; } else { return {done: true}; } } } return iterator; } } return iterable; }
 function iterateOver(...vs) { let iterable = { * [Symbol.iterator]() { for(let v of vs) { yield v; } } } return iterable; } 76
  58. Axel @rauschma Frosty @js_dev #FluentConf Generators: implementing an iterator function*

    objectEntries(obj) { for (let key of Object.keys(obj)) { yield [key, obj[key]]; } } let myObj = { foo: 3, bar: 7 }; for (let [key, value] of objectEntries(myObj)) { console.log(key, value); } // Output: // foo 3 // bar 7 77
  59. Axel @rauschma Frosty @js_dev #FluentConf 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; } } } 78
  60. Axel @rauschma Frosty @js_dev #FluentConf 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 79
  61. Axel @rauschma Frosty @js_dev #FluentConf 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); } }); 80
  62. Axel @rauschma Frosty @js_dev #FluentConf First example: Node.js fs.readFile('config.json', function

    (error, text) { if (error) { console.error('Error'); } else { try { var obj = JSON.parse(text); console.log(JSON.stringify(obj, null, 4)); } catch (e) { console.error('Invalid JSON in file'); } } }); 83
  63. Axel @rauschma Frosty @js_dev #FluentConf First example: Promises readFilePromisified('config.json') .then(function

    (text) { var obj = JSON.parse(text); console.log(JSON.stringify(obj, null, 4)); }) .catch(function (reason) { // File read error or JSON SyntaxError console.error('Error', reason); }); 84
  64. The basics var promise = new Promise( function (resolve, reject)

    { resolve(value); // success reject(error); // failure }); promise.then( function (value) { /* success */ }, function (error) { /* failure */ } );
  65. The basics // Equivalent: promise.catch( function (error) { /* failure

    */ } ); promise.then( null, function (error) { /* failure */ } );
  66. Error handling retrieveFileName() .catch(function () { // Something went wrong,

    use default return 'Untitled.txt'; }) .then(function (fileName) { ... });
  67. function httpGet(url) { return new Promise( function (resolve, reject) {

    var request = new XMLHttpRequest(); request.onreadystatechange = function () { if (this.status === 200) { resolve(this.response); // Success } else { reject(new Error(this.statusText)); } } request.onerror = function () { reject(new Error( 'Error: '+this.statusText)); }; request.open('GET', url); request.send(); }); }
  68. .map() var fileUrls = [ 'http://example.com/file1.txt', 'http://example.com/file2.txt' ]; var promisedTexts

    = fileUrls.map(httpGet); Promise.all(promisedTexts) .then(function (texts) { texts.forEach(function (text) { console.log(text); }); }) .catch(function (reason) { // Receives first rejection among the promises });
  69. Advantages of promises • Cleaner signature • Chaining results, while

    avoiding nesting • Better error handling (chaining, catching exceptions, etc.) • Easier to compose (fork-join, map, etc.)
  70. Axel @rauschma Frosty @js_dev #FluentConf Tail calls • Tail call:

    a function call that is the last action inside a function. • Can be implemented as goto (vs. gosub which needs call stack space). 93
  71. Axel @rauschma Frosty @js_dev #FluentConf Tail calls: examples function f(x)

    { g(x); // no tail call h(x); // tail call } function f(x) { return g(x); // tail call } function f(x) { return 1+g(x); // no tail call } function f(x) { if (x > 0) { return g(x); // tail call } return h(x); // tail call } 94
  72. Axel @rauschma Frosty @js_dev #FluentConf Tail recursion /** Not tail

    recursive */ function fac(x) { if (x <= 0) { return 1; } else { return x * fac(x-1); } } /** Tail recursive */ function fac(n) { return facRec(n, 1); function facRec(i, acc) { if (i <= 1) { return acc; } else { return facRec(i-1, i*acc); } } } 95
  73. Axel @rauschma Frosty @js_dev #FluentConf Loops via recursion function forEach(arr,

    callback, start = 0) { if (0 <= start && start < arr.length) { callback(arr[start]); forEach(arr, callback, start+1); // tail call } } 96
  74. Axel @rauschma Frosty @js_dev #FluentConf Object.assign() Object.assign(target, source_1, source_2, ···)

    • Merge source_1 into target • Merge source_2 into target • Etc. • Return target Warning: • sets properties (may invoke setters), • does not define them (always new) 98
  75. Axel @rauschma Frosty @js_dev #FluentConf ES6 versus lodash let obj

    = { foo: 123 }; // ECMAScript 6 Object.assign(obj, { bar: true }); // obj is now { foo: 123, bar: true } // lodash/Underscore.js _.extend(obj, { bar: true }) // also: _.assign(···) 99
  76. Axel @rauschma Frosty @js_dev #FluentConf Object.assign() // Provide default values

    if properties are missing const DEFAULTS = { logLevel: 0, outputFormat: 'html' }; function processContent(options) { options = Object.assign({}, DEFAULTS, options); ··· } 100
  77. Axel @rauschma Frosty @js_dev #FluentConf Object.assign() // A quick and

    somewhat dirty way to // add methods to a prototype object Object.assign(SomeClass.prototype, { someMethod(arg1, arg2) { ··· }, anotherMethod() { ··· }, }); // Without Object.assign(): SomeClass.prototype.someMethod = function (arg1, arg2) { ··· }; SomeClass.prototype.anotherMethod = function () { ··· }; 101
  78. Axel @rauschma Frosty @js_dev #FluentConf New string methods > 'abc'.repeat(3)

    'abcabcabc' > 'abc'.startsWith('ab') true > 'abc'.endsWith('bc') true > 'foobar'.includes('oo') true 102
  79. Axel @rauschma Frosty @js_dev #FluentConf New array methods > [13,

    7, 8].find(x => x % 2 === 0) 8 > [1, 3, 5].find(x => x % 2 === 0) undefined > [13, 7, 8].findIndex(x => x % 2 === 0) 2 > [1, 3, 5].findIndex(x => x % 2 === 0) -1 103
  80. Axel @rauschma Frosty @js_dev #FluentConf Various other features Also part

    of ECMAScript 6: • Proxies (meta-programming) • Better support for Unicode (strings, regular expressions) 105
  81. Axel @rauschma Frosty @js_dev #FluentConf Transpilation Things that can’t be

    transpiled at all: • Proxies • Subclassable built-in constructors (Error, Array, …) • Tail call optimization Things that are difficult to transpile: • Symbols (via objects) • Generators (transformed to state machines) • WeakMaps, WeakSets (keys stored in values) 106
  82. Axel @rauschma Frosty @js_dev #FluentConf 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 107