Upload
others
View
3
Download
0
Embed Size (px)
Citation preview
1
Version:
ECMAScript oder TypeScript?- das ist hier die Frage -
20.1
2
Ihr Sprecher
Thorsten Maier
Trainer, Berater, Entwickler
@ThorstenMaier
1
2
2
3
JavaScript hat(te) einen
schlechten Ruf
3
4
3
6
“Nearly all of the books about
JavaScript are quite awful.”
The World's Most Misunderstood Programming Language
Douglas Crockford2001
“JavaScript has its share
of design errors.”
“The specification is of
extremely poor quality.”
“Most of the people writing in
JavaScript are not programmers.”
“JavaScript has more in
common with functional
languages like Lisp or
Scheme than with C or Java”
5
6
4
7
Alles besser mit ECMAScript?Ein wenig Historie
8
1995Brendan Eich
Mocha / LiveScript
10 Tage
März 1996Netscape 2.0 / JS 1.0
IE 3.0 / JScript
Juni 1997
ES 1.0
JavaScript JScript ActionScript ES 4
Dez. 2009ES 5
Yahoo, Google, …
Juni 2015ES 2015
JS wird professionell1999
7
8
5
ES 52009
9
ES 20152015
JavaScript wird professionell
for (var i = 0; i < 5; i++) {
var text = "Hello " + i;
}console.log(text);
10
for (var i = 0; i < 5; i++) {
let text = "Hello " + i;
}console.log(text);
Block-Scoped Variablen
9
10
6
Was ist die Ausgabe des folgenden Codes?
11
Häufige Fallstricke in JavaScript
55555
for (var i = 0; i < 5; i++) {setTimeout(function() {console.log(i);
}, 200); }
var Company = (function () {function Company(name) {
this.name = name;
}Company.prototype.getName = function () {
return this.name;
};return Company;
}());
12
Klassen
class Company {
constructor(name) {this.name = name;
}getName() {
return this.name;
}}
11
12
7
13
Vererbung
class Car {
drive() {console.log("Car is driving.");
}}
class Cabrio extends Car {
openTop() {console.log("Top is open.");
}}
-
var Person = (function () {
function Person() {
}Person.sayYourSpecies = function () {
console.log("Ich bin ein Mensch");};return Person;
}());Person.sayYourSpecies();
14
Statische Elemente
class Person {
static sayYourSpecies() {
console.log("Ich bin ein Mensch");}
}Person.sayYourSpecies();
13
14
8
15
Module
-
export const HELLO_WORLD = "Hello World";
import { HELLO_WORLD } from './constants.js'
constants.js
index.js
var add = function (a, b) {
return a + b;
};
16
var add = (a, b) => a + b;
Arrow Functions
15
16
9
var name = "Thorsten";
var t = "Hallo " + name + "!";
17
let name = "Thorsten";
let t = `Hallo ${name}!`;
Template Strings
18
function msgAfterTimeout (who, timeout) {
return new Promise((resolve, reject) => {
setTimeout(() => resolve(`Hello ${who}!`), timeout);
});
}
msgAfterTimeout("Thorsten", 2000)
.then(msg => { console.log(`${msg}`)});
-
Promise
17
18
10
19
ES 2015 - Browser Support
20
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 Foo = function () {
function Foo() {
_classCallCheck(this, Foo);}
_createClass(Foo, [{key: "bar",value: function bar(x) {
return "foo bar " + x;
}}]);
return Foo;
}();
var foo = new Foo();
console.log(foo.bar("baz"));
class Foo {
bar(x) {return `foo bar ${x}`;
}}const foo = new Foo();
console.log(foo.bar("baz"));
ES 2015
ES 5
19
20
11
21
Hört sich doch alles nicht schlecht an.
Warum jetzt noch ?
22
Plain scriptsModulesystems
(Babel, …)
Compilers
(TypeScript, Flow, …)
TypeSystems
21
22
12
23
24
ECMAScript that scales
23
24
13
25
Statisch typisiertes Superset von ECMAScript
Kompiliert zu ECMAScript
26
2.0Statisches Typsystem
ES 2016** Operator
Array.prototype.includes
ES 5Funktionale
Programmierung
Properties
ES 2017await/async
Shared memory
atomics
…
Block-Scope
Module
Klassen
Generatoren
Promises
Collections
Arrow
functions
…
ES 2015
2.5
25
26
14
27
Open Source
28
Gute Tool-Unterstützung
Features from future today
27
28
15
29
CODE COMPLETION
ECMAScript
30
CODE COMPLETION
TypeScript
29
30
16
31
CODE SMARTER
32
CODE SMARTER
JS Dev Kopfwissen?!
lib.es6.d.ts
31
32
17
33
Finde den Fehler
CODE SMARTER
34
CODE SMARTER
33
34
18
35
CODE CONFIDENTLY
36
CODE BETTER (TODAY)
app.ts app.js
(ECMAScript 5)
class Person {name: string;
constructor(name: string) {this.name = name;
}
sayHello() {console.log(`Hello my name is
${this.name}!`);}
}
var Person = /** @class */ (function () {function Person(name) {
this.name = name;}Person.prototype.sayHello = function ()
{console.log("Hello my name is " +
this.name + "!");};return Person;
}());
35
36
19
37
CODE BETTER (TODAY)
ECMAScript 5
async function fetchJson(url) {try {
let request = await fetch(url);let text = await request.text();return JSON.parse(text);
} catch (e) {console.log(`ERROR: ${e.stack}`);
}}
fetchJson('http://example.com/some_file.json').then(obj => console.log(obj));
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {return new (P || (P = Promise))(function (resolve, reject) {function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }step((generator = generator.apply(thisArg, _arguments || [])).next());});};var __generator = (this && this.__generator) || function (thisArg, body) {var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;function verb(n) { return function (v) { return step([n, v]); }; }function step(op) {if (f) throw new TypeError("Generator is already executing.");while (_) try {if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t;if (y = 0, t) op = [0, t.value];switch (op[0]) {case 0: case 1: t = op; break;case 4: _.label++; return { value: op[1], done: false };case 5: _.label++; y = op[1]; op = [0]; continue;case 7: op = _.ops.pop(); _.trys.pop(); continue;default:if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }if (t[2]) _.ops.pop();_.trys.pop(); continue;}op = body.call(thisArg, _);} catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };}};function fetchJson(url) {return __awaiter(this, void 0, void 0, function () {var request, text, error_1;return __generator(this, function (_a) {switch (_a.label) {case 0:_a.trys.push([0, 3, , 4]);return [4 /*yield*/, fetch(url)];case 1:request = _a.sent();return [4 /*yield*/, request.text()];case 2:text = _a.sent();return [2 /*return*/, JSON.parse(text)];case 3:error_1 = _a.sent();console.log("ERROR: " + error_1.stack);return [3 /*break*/, 4];case 4: return [2 /*return*/];}});});}fetchJson('http://example.com/some_file.json').then(function (obj) { return console.log(obj); });
app.ts
38
<3
CODE BIGGER
37
38
20
39
ist wie die Schweiz für Frameworks“
Anders Hejlsberg (chief designer of C# and co-designer of TypeScript)
„
40
2.0
Aug 2016
2.1
Nov 2016
2.2
Feb 2017
2.4
Jun 2017
Apr 2017
2.3Aug 2017
2.5
11 Releases
in 24 Monaten
seeeehr viele neue Feature
Okt 2017
2.6
Okt 2017
2.7Mär 2018
2.8
Mai 2018
2.9
Jul 2018
3.0
39
40
21
41
Ein paar der tollen Feature
42
STRUCTURAL TYPING
41
42
22
43
INTERSECTION TYPES
44
STRING LITERAL TYPES
43
44
23
45
Wer hatte schon mal eine NullPointerException?
JavaScript hat „null“ und „undefined“
46
NULL SAFE
45
46
24
47
Details zum Typsystem
type Shape = { kind: "circle", radius: number } |
{ kind: "rectangle", w: number, h: number } |
{ kind: "square", size: number };
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape. ** 2;
case "rectangle":
return shape.h * shape.w;
case "square":
return shape.size ** 2;
}
throw new Error("Invalid shape");
}
type Shape = { kind: "circle", radius: number } |
{ kind: "rectangle", w: number, h: number } |
{ kind: "square", size: number };
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape. ** 2;
case "rectangle":
return shape.h * shape.w;
case "square":
return shape.size ** 2;
}
throw new Error("Invalid shape");
}
48
LITERAL TYPES
47
48
25
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape. ** 2;
case "rectangle":
return shape.h * shape.w;
case "square":
return shape.size ** 2;
}
assertNever(shape);}
function assertNever(obj: never) {throw new Error("Invalid shape");
}
function getArea(shape: Shape) {
switch (shape.kind) {
case "circle":
return Math.PI * shape. ** 2;
case "rectangle":
return shape.h * shape.w;
case "square":
return shape.size ** 2;
}
assertNever(shape);}
function assertNever(obj: never) {throw new Error("Invalid shape");
}
49
LITERAL TYPES
function test(s: string | string [] | null | undefined) {if (s) {
s;
} else {
s;
}}
function test(s: string | string [] | null | undefined) {if (s) {
s;
} else {
s;
}}
50
Wann ist s == true?
(parameter) s: string | string[]
(parameter) s: string | null | undefined
49
50
26
function test(s: string | string [] | null | undefined) {if (typeof s === "object") {
s;
} else {
s;
}}
function test(s: string | string [] | null | undefined) {if (typeof s === "object") {
s;
} else {
s;
}}
51
Wann ist s === “object”?
(parameter) s: string[] | null
(parameter) s: string | undefined
function test(s: string | string [] | null | undefined) {if (s == undefined) {
s;
} else {
s;
}}
function test(s: string | string [] | null | undefined) {if (s == undefined) {
s;
} else {
s;
}}
52
Wann ist s == “undefined”?
(parameter) s: null | undefined
(parameter) s: string | string[]
51
52
27
function test(s: string | string [] | null | undefined) {if (s === undefined) {
s;
} else {
s;
}}
function test(s: string | string [] | null | undefined) {if (s === undefined) {
s;
} else {
s;
}}
53
Wann ist s === “undefined”?
(parameter) s: undefined
(parameter) s: string | string[] | null
54
TYPES in ECMASCRIPT
{"requires": true,"lockfileVersion": 1,"dependencies": {
"jquery": {"version": "3.2.1"
},"lodash": {
"version": "4.17.4"}
}}
{"requires": true,"lockfileVersion": 1,"dependencies": {
"jquery": {"version": "3.2.1"
},"lodash": {
"version": "4.17.4"}
}}
package.json
53
54
28
55
TYPES in ECMASCRIPT
_.filter("1,2,3".split(",").map(x => parseInt(x)), x => x.);_.filter("1,2,3".split(",").map(x => parseInt(x)), x => x.);
main.js
56https://npm-stat.com/charts.html?package=typescript&from=2016-01-01&to=2020-01-31
55
56
29
57
Ist immer die richtige Wahl?
58
C:\Users\tmaier\myProject>tsc app.ts -w12:20:32 - Compilation complete. Watching for file changes.
COMPILER NOTWENDIG
57
58
30
59
DEBUGGING
60
import $ from "jquery";
$(function(){ alert('Hello');
});
$(function(){ alert('Hello');
});
npm install --save-dev @types/jquery
TYPDEFINITIONEN FÜR BIBLIOTHEKEN
59
60
31
61
ECMAScript oder ?
Wie immer
It depends!
62
?
Kurzes und sehr einfaches Projekt: nein
Refactoring: ja
Unternehmenskritisch: ja
Hohe Fluktuation: ja
Framework: ja
61
62
32
Fragen?
Vielen Dank für Ihre Aufmerksamkeit!
63
64