Slide 1

Slide 1 text

Callable entities in ECMAScript 6 Dr. Axel Rauschmayer 2ality.com 2013-12-04 NDC London

Slide 2

Slide 2 text

Now: functions do triple duty Normal functions (non-method functions) Methods Constructors Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 2 / 1

Slide 3

Slide 3 text

Problems 1 Confusing: function for methods, etc. 2 Risk of using a function incorrectly. E.g.: Calling a method as a normal function Calling a constructor as a normal function 3 No lexical this: normal function inside a method or a constructor: this is shadowed Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 3 / 1

Slide 4

Slide 4 text

Function expression → arrow function function GuiComponent() { // constructor var that = this; var domNode = ...; domNode.addEventListener('click', function () { console.log('CLICK'); that.handleClick(); // `this` is shadowed }); } function GuiComponent() { // constructor var domNode = ...; domNode.addEventListener('click', () => { console.log('CLICK'); this.handleClick(); // `this` not shadowed }); } Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 4 / 1

Slide 5

Slide 5 text

Function declaration → const + arrow function function foo(arg1, arg2) { ... } const foo = (arg1, arg2) => { ... }; Loss: hoisting, function name Many people already avoid function declarations Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 5 / 1

Slide 6

Slide 6 text

IIFE → block + let (function () { // open IIFE var tmp = ...; ... }()); // close IIFE { // open block let tmp = ...; ... } // close block Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 6 / 1

Slide 7

Slide 7 text

Function in object literal → concise method var obj = { myMethod: function (arg1, arg2) { ... } }; let obj = { myMethod(arg1, arg2) { ... } }; Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 7 / 1

Slide 8

Slide 8 text

Constructor → class function ColorPoint(x, y, color) { Point.call(this, x, y); this.color = color; } ColorPoint.prototype = Object.create(Point.prototype); ColorPoint.prototype.constructor = ColorPoint; ColorPoint.prototype.toString = function () { return this.color+' '+Point.prototype.toString.call(this); }; class ColorPoint extends Point { constructor(x, y, color) { super(x, y); // same as super.constructor(x, y) this.color = color; } toString() { return this.color+' '+super(); } } Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 8 / 1

Slide 9

Slide 9 text

Generators Generator function: function *foo(arg1, arg2) { ... } Generator method: let obj = { *bar() { ... } }; Unfortunate mix of new and old: Function declaration syntax Method definition syntax Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 9 / 1

Slide 10

Slide 10 text

Possible solution: generator arrow functions Hypothetical syntax: const generatorFunction = (arg1, arg2) =>* { ... }; Alas, rejected for ECMAScript 6. Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 10 / 1

Slide 11

Slide 11 text

Thin arrow is not needed

Slide 12

Slide 12 text

Thin arrow is not needed Adding methods to an object ECMAScript 5: MyClass.prototype.foo = function (arg1, arg2) { ... }; CoffeeScript MyClass.prototype.foo = (arg1, arg2) -> { ... ECMAScript 6: Object.assign(MyClass.prototype, { foo(arg1, arg2) { ... } }); Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 12 / 1

Slide 13

Slide 13 text

Thin arrow is not needed You can often avoid this $('ul.tabs li').on('click', function () { var tab = $(this); highlightTab(tab); ... }); $('ul.tabs li').on('click', event => { var tab = $(event.target); highlightTab(tab); ... }); Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 13 / 1

Slide 14

Slide 14 text

Thin arrow is not needed API design must change beforeEach(function () { this.addMatchers({ toBeInRange: function (start, end) { ... } }); }); beforeEach(api => { api.addMatchers({ toBeInRange(start, end) { ... } }); }); Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 14 / 1

Slide 15

Slide 15 text

Iterators

Slide 16

Slide 16 text

Iterators Iterables and iterators Iterable: a data structure whose elements can be traversed Iterator: the pointer used for traversal Examples of iterables: Arrays Sets Results produced by tool functions Examples (built-in, for objects): keys(), values(), entries() All array-like DOM objects (eventually) Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 16 / 1

Slide 17

Slide 17 text

Iterators Iterables and iterators import {iterate} from '@iter'; // symbol let iterable = ['a', 'b']; let iterator = iterable[iterate](); iterator.next(); // { value: 'a' } iterator.next(); // { value: 'b' } iterator.next(); // { done: true } [iterate]() ... Iterable: traversable data structure next() Iterator: pointer for traversing iterable returns Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 17 / 1

Slide 18

Slide 18 text

Iterators Example: iterator (1/2) import {iterate} from '@iter'; // symbol function iterArray(arr) { ... return { [iterate]() { // is iterable return this; // returns iterator }, next() { // is iterator ... // code is on next slide } }; } for (let elem of iterArray(['a', 'b'])) { console.log(elem); } Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 18 / 1

Slide 19

Slide 19 text

Iterators Example: iterator (2/2) function iterArray(arr) { var i = 0; return { ... next() { if (i < arr.length) { return { value: arr[i++] }; } else { return { done: true }; } } }; } Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 19 / 1

Slide 20

Slide 20 text

Generators

Slide 21

Slide 21 text

Generators function* generatorFunction() { ... yield x; ... } generatorObject returns next() yield next() yield Generators: suspend and resume a function Shallow coroutines [4]: only function body is suspended. Uses: iterators, simpler asynchronous programming. Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 21 / 1

Slide 22

Slide 22 text

Generators Generators: example Suspend via yield (“resumable return”): function *generatorFunction() { yield 0; yield 1; yield 2; } Start and resume via next(): let genObj = generatorFunction(); console.log(genObj.next()); // { value: 0 } console.log(genObj.next()); // { value: 1 } console.log(genObj.next()); // ( value: 2 } console.log(genObj.next()); // ( done: true } Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 22 / 1

Slide 23

Slide 23 text

Generators Generators: implementing an iterator function *iterArray(arr) { for (let i=0; i < arr.length; i++) { yield arr[i]; } } Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 23 / 1

Slide 24

Slide 24 text

Generators Generators: implementing an iterator An iterator for nested arrays: function *iterTree(tree) { if (Array.isArray(tree)) { // inner node for(let i=0; i < tree.length; i++) { yield* iterTree(tree[i]); // recursion } } else { // leaf yield tree; } } Difficult to write without recursion. Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 24 / 1

Slide 25

Slide 25 text

Generators Generators: asynchronous programming Using the task.js library: spawn(function * () { try { var [foo, bar] = yield join( read("foo.json"), read("bar.json") ).timeout(1000); render(foo); render(bar); } catch (e) { console.log("read failed: " + e); } }); Wait for asynchronous calls via yield (internally based on promises). Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 25 / 1

Slide 26

Slide 26 text

Wrapping up

Slide 27

Slide 27 text

Wrapping up Conclusion Have the problems been fixed? 1 Clear separation of concerns w.r.t. functions in ECMAScript 6 2 Incorrect uses: Prevented: can’t call a class as a function No help with: calling extracted methods 3 Shadowing this in normal function – prevented via arrow functions. Dr. Axel Rauschmayer (2ality.com) Callable entities in ECMAScript 6 2013-12-04 27 / 1

Slide 28

Slide 28 text

Thank you! Blog posts on ECMAScript 6: 2ality.com/search/label/esnext