ecmascript 6 im produktivbetrieb

85
ECMAScript 6 im Produktivbetrieb hennesd / pixelio.de

Upload: sebastian-springer

Post on 15-Feb-2017

518 views

Category:

Software


0 download

TRANSCRIPT

Page 1: ECMAScript 6 im Produktivbetrieb

ECMAScript 6 im Produktivbetrieb

hennesd / pixelio.de

Page 2: ECMAScript 6 im Produktivbetrieb

WHO AM I?

• Sebastian Springer

• aus München

• arbeite bei Mayflower

• https://github.com/sspringer82

• @basti_springer

• Consultant, Trainer, Autor

Page 3: ECMAScript 6 im Produktivbetrieb

http://kangax.github.io/compat-table/es6/

Page 4: ECMAScript 6 im Produktivbetrieb

Transpiler

6 → 5

Page 5: ECMAScript 6 im Produktivbetrieb

Transpiler

ES6 wird noch nicht überall unterstützt, also müssen ES6-Features in ES5 übersetzt werden.

Page 6: ECMAScript 6 im Produktivbetrieb

ES6 Code

class User { constructor (name) { this.name = name; } sayHello() { alert(`Hello ${this.name}`); }}

Page 7: ECMAScript 6 im Produktivbetrieb

Transpiled Code"use strict"; var _createClass = (function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; })();function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }var User = (function () { function User(name) { _classCallCheck(this, User); this.name = name; } _createClass(User, [{ key: "sayHello", value: function sayHello() { alert("Hello " + this.name); } }]); return User; })();

Page 8: ECMAScript 6 im Produktivbetrieb
Page 9: ECMAScript 6 im Produktivbetrieb

FeaturesArray comprehensions

Arrow functions Async functions

Async generator functions Classes

Class properties Computed property names

Constants Decorators

Default parameters Destructuring

Exponentiation operator For-of

Function bind

Generators Generator comprehensions

Let scoping Modules

Module export extensions Object rest/spread

Property method assignment Property name shorthand

Rest parameters React

Spread Template literals Type annotations Unicode regex

Page 10: ECMAScript 6 im Produktivbetrieb

Babel

$ npm install -g babel

$ babel app.js

$ babel -o app.dist.js app.js

$ babel src -d dist

Page 11: ECMAScript 6 im Produktivbetrieb

Grunt Integration$ npm install grunt grunt-babel

module.exports = function(grunt){ grunt.loadNpmTasks('grunt-babel'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.initConfig({ "babel": { options: { sourceMap: true }, dist: { files: { "dist/app.js": “app.js" } } }, "watch": { scripts: { files: [“app.js"], tasks: [“babel"] } } }); grunt.registerTask("default", ["babel"]);};

Page 12: ECMAScript 6 im Produktivbetrieb

Grunt Integration

$ grunt watch Running "watch" task Waiting... >> File "app.js" changed. Running "babel:dist" (babel) task

Done, without errors.

Page 13: ECMAScript 6 im Produktivbetrieb

Klassen

Manfred Jahreis / pixelio.de

Page 14: ECMAScript 6 im Produktivbetrieb

Class

Syntactical Sugar, um das Prototypen-Konzept von JavaScript

Page 15: ECMAScript 6 im Produktivbetrieb

Classclass Task { constructor(title) { this.title = title; this.state = 'todo'; } complete() { this.state = 'done'; } }

Page 16: ECMAScript 6 im Produktivbetrieb

Class

function Task (title) { this.title = title; this.state = 'todo'; } Task.prototype.complete = function () { this.state = 'done'; };

Page 17: ECMAScript 6 im Produktivbetrieb

Class - staticclass Task { ... static createTask(title) { return new Task(title); }} var task2 = Task.createTask('my2ndTask');

Page 18: ECMAScript 6 im Produktivbetrieb

Class

function Task (title) { this.title = title; this.state = 'todo'; } Task.createTask = function (title) { return new Task(title);};

Page 19: ECMAScript 6 im Produktivbetrieb

Class - get/setclass Task { get description() { console.log('description getter'); return this._description; } set description(val) { console.log('description setter'); this._description = val; } }

Page 20: ECMAScript 6 im Produktivbetrieb

Class - inheritance

class story extends task { constructor (title, description) { this.description = description; super(title); }}

Page 21: ECMAScript 6 im Produktivbetrieb

Module

URSfoto / pixelio.de

Page 22: ECMAScript 6 im Produktivbetrieb

SystemJS

Page 23: ECMAScript 6 im Produktivbetrieb

SystemJS

Polyfill für ES6-Module. Unterstützen import und export.

systemjs-builder: Buildsystem für Production-Build.

Page 24: ECMAScript 6 im Produktivbetrieb

SystemJS - im Browser<script src="system.js"></script> <script> System.config({ baseURL: '/jsdays/es6/modules/systemjs/', transpiler: 'babel', map: { babel: 'browser.js' } }); System.import('import.js'); </script>

Page 25: ECMAScript 6 im Produktivbetrieb

JSPM - SystemJS Package Manager

Paketmanager auf Basis von SystemJS. Bibliotheken können installiert und direkt verwendet werden.

$ jspm install jquery

import $ from ‘jquery’;

Page 26: ECMAScript 6 im Produktivbetrieb

SystemJS - Build

$ npm install grunt grunt-systemjs-builder

System.config({ transpiler: 'babel', map: { babel: 'browser.js' } });

Page 27: ECMAScript 6 im Produktivbetrieb

SystemJS - Buildmodule.exports = function(grunt){ grunt.loadNpmTasks("grunt-systemjs-builder"); grunt.initConfig({ systemjs: { options: { sfx: true, baseURL: ".", configFile: "config.js", minify: true, build: { mangle: false } }, dist: { files: [{ "src": "app/import.js", "dest": "dist/app.min.js" }] } } });};

Page 28: ECMAScript 6 im Produktivbetrieb

SystemJS - Build

<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title></title> </head> <body> <script src="dist/app.min.js"></script> </body> </html>

Page 29: ECMAScript 6 im Produktivbetrieb

Arrow Functions

Jürgen Hüsmert / pixelio.de

Page 30: ECMAScript 6 im Produktivbetrieb

Arrow Functionsclass List { constructor(tasks) { this.tasks = tasks; } getDone() { return this.tasks .filter(task => task.state === 'done'); }}

Page 31: ECMAScript 6 im Produktivbetrieb

Arrow Functionsvar myObj = { clicked: false, init: function() { document.addEventListener('click', function() { this.clicked = true; } ); }}; myObj.init();

Page 32: ECMAScript 6 im Produktivbetrieb

Arrow Functions

var myObj = { clicked: false, init: function() { document.addEventListener('click', () => { this.clicked = true; }); }}; myObj.init();

Page 33: ECMAScript 6 im Produktivbetrieb

Arrow Functions

Sind an den Kontext ihrer Definition gebunden.

Page 34: ECMAScript 6 im Produktivbetrieb

Arrow Functions

var myObj = { name: 'Klaus', getName: () => { return this.name; }}; console.log(myObj.getName());

Page 35: ECMAScript 6 im Produktivbetrieb

var myObj = { name: 'Klaus', getFunc: function() { return () => { return this.name; } }}; var my2ndObj = { name: 'Lisa'}; var func = myObj.getFunc();console.log(func.call(my2ndObj))

Arrow Functions

Page 36: ECMAScript 6 im Produktivbetrieb

Scoping

Peter Smola / pixelio.de

Page 37: ECMAScript 6 im Produktivbetrieb

Scoping

Global: Variablen sind überall verfügbar. Function: Variablen sind in der aktuellen Funktion und allen

Subroutinen verfügbar. Closure: Erstellender Kontext einer Funktion und die Funktion

selbst

Page 38: ECMAScript 6 im Produktivbetrieb

letVariable ist nur im aktuellen Block gültig.

Variablen werden innerhalb des Block gehoistet.

for (let task in tasks) { console.log(task);}

Page 39: ECMAScript 6 im Produktivbetrieb

const

Nicht veränderliche Werte

const pi = 3.14;

Page 40: ECMAScript 6 im Produktivbetrieb

Destructuring

Rahel Szielis / pixelio.de

Page 41: ECMAScript 6 im Produktivbetrieb

Destructuring

Strukturen in einzelne Variablen zerlegen

Page 42: ECMAScript 6 im Produktivbetrieb

Destructuring

var person = {name: 'Klaus', age: 42}; var {name, age} = person;

var arr = [1, 2, 3]; var [one, two, three] = arr;

var person = {name: 'Klaus', age: 42}; var {name: firstname, age} = person;

Page 43: ECMAScript 6 im Produktivbetrieb

Default Parameters

Page 44: ECMAScript 6 im Produktivbetrieb

Default Parameters

Jeder Parameter ohne Wert ist undefined. Möchte man das ändern, geht das im Moment nur mit einem kleinen Hack.

Page 45: ECMAScript 6 im Produktivbetrieb

Früher

function testDefaults(value) { value = value || 'default'; console.log(value);} testDefaults(); // defaulttestDefaults('myValue'); // myValue

Page 46: ECMAScript 6 im Produktivbetrieb

Mit ECMAScript 6

function testDefaults(value = 'default') { console.log(value);} testDefaults(); // defaulttestDefaults('myValue'); // myValue

Mit ECMAScript 6 kann man den Parametern Standardwerte zuweisen, die verwendet werden, falls kein Wert beim Aufruf

übergeben wird.

Page 47: ECMAScript 6 im Produktivbetrieb

Default Parameters

Default Parameters können an jeder Stelle der Parameterliste verwendet werden.

function testDefaults(a = 'foo', b, c = 'bar') { console.log(arguments); } testDefaults(); // foo undefined bar

Page 48: ECMAScript 6 im Produktivbetrieb

Default ParametersWird undefined explizit übergeben, wird trotzdem der default-

Wert benutzt.

function testDefaults(a, b = 1) { return a + b;} var b; testDefaults(2, b); // 3

Page 49: ECMAScript 6 im Produktivbetrieb

Default ParametersEs können beliebige Werte verwendet werden: Primäre

Datentypen, Objekte, Arrays und Funktionsaufrufe.

function testDefaults( pri = 'hello', obj = {name: 'world'},arr = [1,2,3], funcVal = myFunc()){ console.log(pri, obj, arr, funcVal);}

Page 50: ECMAScript 6 im Produktivbetrieb

Default ParametersKein Zugriff über arguments auf Default Parameters.

arguments.length wird nicht angepasst, wenn ein Default Parameter zum Einsatz kommt.

function testDefaults(a = 1) { console.log(arguments.length); console.log(arguments[0]);} testDefaults(); // 0 undefined

Page 51: ECMAScript 6 im Produktivbetrieb

Default Parameters

Die Default Parameter werden zur Laufzeit ausgewertet. Es wird also bei jedem Funktionsaufruf ein neues Objekt erzeugt.

function testDefaults(arr = []) { console.log(arr); return arr;} var myArr1 = testDefaults();var myArr2 = testDefaults();

Page 52: ECMAScript 6 im Produktivbetrieb

Default Parameters

Zugriff von späteren Argumenten auf frühere.

function testDefaults( arr = [1,2,3], length = arr.length) { console.log(arr); console.log(length);}

Page 53: ECMAScript 6 im Produktivbetrieb

Template Strings

Helmut / pixelio.de

Page 54: ECMAScript 6 im Produktivbetrieb

Template Strings

var str1 = 'Hello World'; var str2 = "Hello World"; var str3 = `Hello World`;

Page 55: ECMAScript 6 im Produktivbetrieb

Template Strings

var str4 = `1 + 1 = ${1 + 1}`; console.log(str4);

Page 56: ECMAScript 6 im Produktivbetrieb

Template Strings

`1 + 1 = ${1 + 1}`

“1 + 1 = “ + (1 + 1)

1 + 1 = 2

Page 57: ECMAScript 6 im Produktivbetrieb

Template Strings

var str5 = `Hallo Welt!`;

Multi-Line

Page 58: ECMAScript 6 im Produktivbetrieb

Taged Template Strings

function tag(string, ...values) { console.log('String:', string); console.log('Values:', values); return ‘MyString’;} tag `Hallo ${1} Welt ${2}`;

Page 59: ECMAScript 6 im Produktivbetrieb

Generators

Andreas Hermsdorf / pixelio.de

Page 60: ECMAScript 6 im Produktivbetrieb

Ein Generator ist eine first-class coroutine, die einen angehaltenen Ausführungskontext repräsentiert.

Page 61: ECMAScript 6 im Produktivbetrieb

Generators

var gFunction = function*() { // your code in here}

var generator = gFunction();

Page 62: ECMAScript 6 im Produktivbetrieb

Generator Functions

var gFunction = function*() { yield 'Hello'; yield 'World'; }

Page 63: ECMAScript 6 im Produktivbetrieb

Generator

var generator = gFunction();while (true) { var current = generator.next(); if (current.done) { break; } console.log(current.value); }

Page 64: ECMAScript 6 im Produktivbetrieb

Generator

generator.next(); // {value: ‘Hello’, done: false}generator.next(); // {value: ‘World’, done: false}generator.next(); // {value: undefined, done: true}generator.next(); // {value: undefined, done: true}

Page 65: ECMAScript 6 im Produktivbetrieb

var gFunction = function*() { var i i = yield 'first'; i = yield 'second' + i; yield 'third' + i; } var g = gFunction();console.log(g.next());console.log(g.next(1));console.log(g.next(2));

Generator Input

Page 66: ECMAScript 6 im Produktivbetrieb

Generators und for…of

var gFunction = function*() { yield 'Hello'; yield 'World'; } var generator = gFunction();for (let i of generator) { console.log(i); }

Page 67: ECMAScript 6 im Produktivbetrieb

Promises

Lupo / pixelio.de

Page 68: ECMAScript 6 im Produktivbetrieb

Promises

Versprechen auf die Erledigung einer asynchronen Aufgabe.

Events?

Gut für Fire and Forget, nicht aber, wenn es um Erfolg/Misserfolg geht.

Page 69: ECMAScript 6 im Produktivbetrieb

Promises

• Fulfill: Aktion war erfolgreich.

• Reject: Aktion war nicht erfolgreich.

• Pending: Noch kein fulfill oder reject

• Settled: fulfilled oder rejected

Page 70: ECMAScript 6 im Produktivbetrieb

Promisesvar promise = new Promise(function(resolve, reject) { if (true) { resolve("Everything is fine"); } else { reject("Something went wrong"); }});promise.then(function success(data) { console.log(data);}, function failure(err) { console.log(err);});

Page 71: ECMAScript 6 im Produktivbetrieb

PromisesChaining

function async() { return new Promise(function (res, rej) { res(1); });} async().then(function (v) { return v + 1; }).then(function (v) { return v + 1; }).then(function (v) { console.log(`value: ${v + 1}`);});

Page 72: ECMAScript 6 im Produktivbetrieb

(new Promise(function (res, rej) { console.log('Promise 1'); res(1); })).then(function (v) { console.log('Promise 2'); return new Promise(function (res, rej) { rej('Failed at Promise 2'); });}).then(function(v) { console.log('Promise 3'); return new Promise(function (res) { res(v + 1); })}).then(function (v) { console.log(`last Promise ${v}`)}, function (err) { console.log(`Failed: ${err}`);});

Page 73: ECMAScript 6 im Produktivbetrieb

Flusssteuerung - allfunction async(number, timeout) { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(`Promise Nr. ${number} resolved`); resolve(number); }, timeout); });} Promise.all([ async(1, 1000), async(2, 2000), async(3, 3000) ]).then(function (data) { console.log(`all promises resolved ${data}`);});

Page 74: ECMAScript 6 im Produktivbetrieb

Flusssteuerung - all

P1

P2

P3

Page 75: ECMAScript 6 im Produktivbetrieb

Flusssteuerung - racefunction async(number, timeout) { return new Promise(function (resolve, reject) { setTimeout(function () { console.log(`Promise Nr. ${number} resolved`); resolve(number); }, timeout); });} Promise.race([ async(1, 1000), async(2, 2000), async(3, 3000) ]).then(function (data) { console.log(`one promise resolved ${data}`);});

Page 76: ECMAScript 6 im Produktivbetrieb

Flusssteuerung - all

P1

P2

P3

Page 77: ECMAScript 6 im Produktivbetrieb

Rest

Page 78: ECMAScript 6 im Produktivbetrieb

Rest

arguments ist böse!

arguments ist kein richtiges Array-Objekt

Rest Parameter steht für eine beliebige Anzahl von Argumenten.

Argumentenliste wird in ein Array umgewandelt.

Page 79: ECMAScript 6 im Produktivbetrieb

Rest

function sayHello(...args) { console.log('Number of arguments: ' + args.length); } sayHello('Hallo', 'München');

Page 80: ECMAScript 6 im Produktivbetrieb

Spread

CFalk / pixelio.de

Page 81: ECMAScript 6 im Produktivbetrieb

Spread

Der Spread Operator kann überall eingesetzt werden, wo ein Array in eine Argumentenliste umgewandelt werden soll.

Verhält sich also ähnlich wie apply.

Page 82: ECMAScript 6 im Produktivbetrieb

Spread

function sayHello(greeting, name) { console.log(`${greeting} ${name}`);} var args = ['Servus', 'München']; sayHello.apply(null, args);

Page 83: ECMAScript 6 im Produktivbetrieb

Spread

function sayHello(greeting, name) { console.log(`${greeting} ${name}`);} var args = ['Servus', 'München']; sayHello(...args);

Page 84: ECMAScript 6 im Produktivbetrieb

Fragen?

Rainer Sturm / pixelio.de

Page 85: ECMAScript 6 im Produktivbetrieb

KONTAKT

Sebastian Springer [email protected]

Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland

@basti_springer

https://github.com/sspringer82