The State of JavaScript (2015)

34
the state of javascript

Transcript of The State of JavaScript (2015)

Page 1: The State of JavaScript (2015)

the state of javascript

Page 2: The State of JavaScript (2015)

hi, i’m domenic Google Chrome TC39 WHATWG HTML and Streams Standards Promises jsdom

Page 3: The State of JavaScript (2015)

let’s talk about

> where we’ve come from> javascript today> new platform innovations> where we’re going

Page 4: The State of JavaScript (2015)

where we’vecome from

Page 5: The State of JavaScript (2015)

history

1995: form validation, image rollovers

1997: ECMA-262 edition 1, Internet Explorer 4, DHTML

1999: ES3 (function expressions, try/catch/finally, regexps, …)

2005: Ajax

2006: jQuery

2008: V8 (the speed race begins), JS: The Good Parts

2009: ES5, Node.js, PhoneGap, JSConf, ServerJS/CommonJS

2010: Backbone.js, RequireJS

2012: Windows 8, Nodecopter

2013: Nodebots, next-gen MVC, Extensible Web, asm.js

2015: io.js, ES2015, MS Edge, Node.js 4, web assembly

Page 6: The State of JavaScript (2015)

javascripttoday

Page 7: The State of JavaScript (2015)

es2015 is here

Page 8: The State of JavaScript (2015)

es2015: syntaxClass sugar: class, extends, super

Arrow functions: arr.map(x => x * x)

Destructuring: var { x, y } = getPoint()

Rest/spread: var [first, …rest] = els; Math.max(...myArray)

Parameter defaults: function parseInt(x, base = 10) { }

Block scoping: { let x = 5; const y = 10; }

Page 9: The State of JavaScript (2015)

es2015: data structures

Map: object-to-object O(1) access time

Set: O(1) lookup and storage

WeakMap/WeakSet: private state and branding

Iteration protocol: for-of across anything, even user iterables

Page 10: The State of JavaScript (2015)

es2015: game-changersGenerators: lazy sequences and async/await-like syntax

Promises: standardized async; play well with generators

Proxies: virtual objects, no more .get(…)/.set(…, …)!

Template strings: jsx`<a href="${url}">${text}</a>`

Subclassable built-ins: class Elements extends Array { … }

Page 11: The State of JavaScript (2015)

es2015 in the wild

Page 12: The State of JavaScript (2015)

new code styles

{ "no-var": 2, "object-shorthand": 2, "prefer-arrow-callback": 2, "prefer-const": 2, "prefer-template": 2}

https://github.com/tmpvar/jsdom/blob/master/lib/jsdom/living/document-type.js

"use strict";const NODE_TYPE = require("../living/node-type");

const privates = Symbol("DocumentType internal slots");

module.exports = core => { core.DocumentType = class DocumentType extends core.Node { constructor(secret, ownerDocument, name, publicId, systemId) { if (secret !== privates) { throw new TypeError("Invalid constructor"); }

super(ownerDocument); this[privates] = { name, publicId, systemId }; }

get name() { return this[privates].name; } ⋮

Page 13: The State of JavaScript (2015)

promises everywhere

generators for async

https://github.com/domenic/wattsi-server/blob/master/lib/app.js

const outDirectory = randomDirectoryName();yield mkdirp(outDirectory);

try { try { const result = yield execFile(config.wattsiPath, [sourceFilePath, outDirectory, caniuseFilePath, w3cbugsFilePath]);

const outputFile = path.join(outDirectory, "output.txt"); yield fs.writeFile(outputFile, `${result.stdout}${result.stderr}`, { encoding: "utf-8" }); } catch (e) { if (e.stdout) e.message = `${e.stdout}${e.stderr}`; this.throw(e, 400); }

const zipFilePath = `${outDirectory}.zip`; yield execFile("7za", ["a", "-tzip", "-r", zipFilePath, `./${outDirectory}/*`]);

this.type = "application/zip"; this.body = fs.createReadStream(zipFilePath);} finally { yield rimraf(outDirectory);}

Page 14: The State of JavaScript (2015)

transpile for browsersand nonstandard features

https://github.com/unicorn-standard/react-callback-register

@callbackRegisterclass MyComponent extends React.Component { static propTypes = { onClick: React.PropTypes.func }

@callbackRegister.on('click') descriptiveName() { // Do your stuff }

render() { return <div {...this.callbacks} /> }}

Page 15: The State of JavaScript (2015)

new platforminnovations

Page 16: The State of JavaScript (2015)

#extendthewebforward

extensiblewebmanifesto.org

Page 17: The State of JavaScript (2015)

class CustomImage extends HTMLElement { constructor(src) { super(); if (src !== undefined) this.src = src; }

get src() { return (new URL(this.getAttribute("src"), this.baseURI)).href; } set src(value) { this.setAttribute("src", value); }

[Element.attributeChanged](name) { if (name === "src") updateShadowDOM(this, this.src); }}

document.registerElement("custom-image", CustomImage);https://github.com/w3c/webcomponents/blob/gh-pages/proposals/Constructor-Dmitry.md

custom elements

Page 18: The State of JavaScript (2015)

https://www.npmjs.com/search?q=service+worker

toolbox.precache(['/index.html', '/site.css', '/images/logo.png']);

toolbox.cache('/data/2014/posts.json');toolbox.uncache('/data/2013/posts.json');

toolbox.router.get('/:foo/index.html', (req, values) => { return new Response( `Handled a request for ${req.url} with :foo as ${values.foo}`);});

toolbox.router.get('/myapp/a', toolbox.networkFirst);toolbox.router.get('/myapp/b', toolbox.networkOnly);toolbox.router.get('/myapp/c', toolbox.cacheFirst);toolbox.router.get('/myapp/:page', toolbox.cacheOnly);toolbox.router.get('/(.*)', toolbox.fastest);

https://github.com/GoogleChrome/sw-toolbox

service workers

Page 19: The State of JavaScript (2015)

registerPaint('circle', class { static get inputProperties() { return ['--circle-color']; }

paint(ctx, geom, properties) { // Change the fill color. ctx.fillStyle = properties.get('--circle-color');

// Determine the center point and radius. const x = geom.width / 2; const y = geom.height / 2; const radius = Math.min(x, y);

// Draw the circle \o/ ctx.beginPath(); ctx.arc(x, y, radius, 0, 2 * Math.PI, false); ctx.fill(); }});

#myElement { --circle-color: red; background-image: paint(circle);}

https://drafts.css-houdini.org/css-paint-api/#example-1

custom paint

Page 20: The State of JavaScript (2015)

where we’regoing

Page 21: The State of JavaScript (2015)

https://tc39.github.io/ecma262/

Page 22: The State of JavaScript (2015)

spec version numbers are bullshites6, es2015, es2016… who cares?

you should not.

Page 23: The State of JavaScript (2015)

coming soon

Page 24: The State of JavaScript (2015)

async function getUserImages() { const response = await fetch("http://example.com/users"); const users = await response.json();

return Promise.all(users.map(async (u) => { return { name: u.name, image: (await fetch(u.imageUrl)).body }; }));}

async/await

Page 25: The State of JavaScript (2015)

for (let i = 0; i < maxIterations; ++i) { const zRe24 = SIMD.Float32x4.mul(zRe4, zRe4); const zIm24 = SIMD.Float32x4.mul(zIm4, zIm4);

const mi4 = SIMD.Float32x4.lessThanOrEqual(SIMD.Float32x4.add(zRe24, zIm24), four4);

if (mi4.signMask === 0x00) { break; }

const newRe4 = SIMD.Float32x4.sub(zRe24, zIm24); const newIm4 = SIMD.Float32x4.mul(SIMD.Float32x4.mul(two4, zRe4), zIm4); zRe4 = SIMD.Float32x4.add(cRe4, newRe4); zIm4 = SIMD.Float32x4.add(cIm4, newIm4); count4 = SIMD.Int32x4.add(count4, SIMD.Int32x4.and(mi4, on4));}

SIMD.js

https://github.com/PeterJensen/mandelbrot/blob/master/js/mandelbrot.js

Page 26: The State of JavaScript (2015)

watch out for

Page 27: The State of JavaScript (2015)

// 64 bit integersconst fifteen = 5UL + 10UL;

// Memory-efficient structurally-equal "structs"const Point = new ValueType({ x: float64, y: float64 });const point = new Point({ x: 1.5, y: 2.4 });assert(point === new Point({ x: 1.5, y: 2.4 }));

// Custom literals and operator overloadsconst romaineLettuce = 0x3B5323FFrgba;const length = 50percent + 10em + 5px;el.css.width += 2rem;

value types

https://github.com/nikomatsakis/typed-objects-explainer/

Page 28: The State of JavaScript (2015)

class BusinessLogic { @performance doImportantComputation() { // ... }}

(new BusinessLogic()).doImportantComputation();// => doImportantComputation: 102ms

decorators

https://www.npmjs.com/package/decorator-performance

Page 29: The State of JavaScript (2015)

startSpinner();

const p = fetch(url) .then(r => r.json()) .then(data => fetch(data.otherUrl)) .then(res => res.text()) .then(text => updateUI(text)) .catch(err => showUIError(err)) .finally(stopSpinner);

cancelButton.onclick = () => p.cancel();

cancelable promises

Page 30: The State of JavaScript (2015)

async function* directoryEntries(path) { const dir = await opendir(path);

try { let entry; async for (const entry of readdir(dir)) { yield path.resolve(entry); } } finally { await closedir(dir); }}

async iterators

Page 31: The State of JavaScript (2015)

<script type="module">

import a from "./a.js";import { b } from "../b.js";import $ from "https://cdn.example.com/jquery.js";

</script>

module loading

Page 32: The State of JavaScript (2015)

one last thing…

Page 33: The State of JavaScript (2015)

web assembly!?!?https://github.com/WebAssembly/design

Page 34: The State of JavaScript (2015)