ECMAScript 6 im Produktivbetrieb

Preview:

Citation preview

ECMAScript 6 im Produktivbetrieb

hennesd / pixelio.de

WHO AM I?

• Sebastian Springer

• aus München

• arbeite bei Mayflower

• https://github.com/sspringer82

• @basti_springer

• Consultant, Trainer, Autor

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

Transpiler

6 → 5

Transpiler

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

ES6 Code

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

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; })();

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

Babel

$ npm install -g babel

$ babel app.js

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

$ babel src -d dist

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"]);};

Grunt Integration

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

Done, without errors.

Klassen

Manfred Jahreis / pixelio.de

Class

Syntactical Sugar, um das Prototypen-Konzept von JavaScript

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

Class

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

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

Class

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

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

Class - inheritance

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

Module

URSfoto / pixelio.de

SystemJS

SystemJS

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

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

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>

JSPM - SystemJS Package Manager

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

$ jspm install jquery

import $ from ‘jquery’;

SystemJS - Build

$ npm install grunt grunt-systemjs-builder

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

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" }] } } });};

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>

Arrow Functions

Jürgen Hüsmert / pixelio.de

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

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

Arrow Functions

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

Arrow Functions

Sind an den Kontext ihrer Definition gebunden.

Arrow Functions

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

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

Scoping

Peter Smola / pixelio.de

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

letVariable ist nur im aktuellen Block gültig.

Variablen werden innerhalb des Block gehoistet.

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

const

Nicht veränderliche Werte

const pi = 3.14;

Destructuring

Rahel Szielis / pixelio.de

Destructuring

Strukturen in einzelne Variablen zerlegen

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;

Default Parameters

Default Parameters

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

Früher

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

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.

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

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

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);}

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

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();

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);}

Template Strings

Helmut / pixelio.de

Template Strings

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

Template Strings

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

Template Strings

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

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

1 + 1 = 2

Template Strings

var str5 = `Hallo Welt!`;

Multi-Line

Taged Template Strings

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

Generators

Andreas Hermsdorf / pixelio.de

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

Generators

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

var generator = gFunction();

Generator Functions

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

Generator

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

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}

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

Generators und for…of

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

Promises

Lupo / pixelio.de

Promises

Versprechen auf die Erledigung einer asynchronen Aufgabe.

Events?

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

Promises

• Fulfill: Aktion war erfolgreich.

• Reject: Aktion war nicht erfolgreich.

• Pending: Noch kein fulfill oder reject

• Settled: fulfilled oder rejected

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);});

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}`);});

(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}`);});

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}`);});

Flusssteuerung - all

P1

P2

P3

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}`);});

Flusssteuerung - all

P1

P2

P3

Rest

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.

Rest

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

Spread

CFalk / pixelio.de

Spread

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

Verhält sich also ähnlich wie apply.

Spread

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

Spread

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

Fragen?

Rainer Sturm / pixelio.de

KONTAKT

Sebastian Springer sebastian.springer@mayflower.de

Mayflower GmbH Mannhardtstr. 6 80538 München Deutschland

@basti_springer

https://github.com/sspringer82

Recommended