{"id":175,"date":"2018-02-08T14:44:19","date_gmt":"2018-02-08T12:44:19","guid":{"rendered":"http:\/\/carsten.familie-schumann.info\/blog\/?page_id=175"},"modified":"2020-03-18T13:29:32","modified_gmt":"2020-03-18T11:29:32","slug":"es6-es7-es8-features","status":"publish","type":"page","link":"https:\/\/carsten.familie-schumann.info\/blog\/es6-es7-es8-features\/","title":{"rendered":"ES6\/ES7\/ES8 Features"},"content":{"rendered":"<p>ES6(ECMAScript 2015), ES7(ECMAScript 2016) und ES8(ECMAScript 2017) bringen einen Haufen Vorteile gegen\u00fcber normalem Javascript. In diesem Artikel m\u00f6chte ich die praktischsten vorstellen.<\/p>\n<h1>ES6<\/h1>\n<p>ES6 wurde im Jahre 2015 finalisiert und war das bedeutendste Upgrade der JavaScript Programmiersprache. Dabei wurden viele Konzepte aus anderen Programmiersprachen \u00fcbernommen und Funktionen aus externen Bibliotheken in den Sprachkern integriert. W\u00e4hrend alte Applikationen und Skript auch unter ES6 weiter funktionierten, ergaben sich viele neue M\u00f6glichkeiten, mit weniger Aufwand schnelleren und \u00fcbersichtlicheren Code zu generieren.<\/p>\n<h2>Neue Methoden<\/h2>\n<p>Diversen Standardobjekten wurden neue Methoden verpasst. Speziell beim String-Datentyp kann man sich nun in vielen Stellen das Gehempel mit regul\u00e4ren Ausdr\u00fccken f\u00fcr Standardabfragen sparen. Die Beispiele sollten selbsterkl\u00e4rend sein. Zu den <em>SafeInteger<\/em>s empfehle ich den <a href=\"https:\/\/developer.mozilla.org\/de\/docs\/Web\/JavaScript\/Reference\/Global_Objects\/Number\/isSafeInteger\">Artikel in der Mozilla MDN<\/a>.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ String\r\n&quot;Hallo&quot;.startsWith(&quot;He&quot;);\r\n&quot;Features&quot;.endsWith(&quot;es&quot;);\r\n&quot;ha&quot;.repeat(2); \/\/ ==&amp;gt; &quot;haha&quot;\r\n&quot;abcdef&quot;.includes(&quot;bcd&quot;);\r\n\r\n\/\/ Number\r\nNumber.EPSILON;\r\nNumber.MAX_SAFE_INTEGER; \/\/ INT_MAX bei c\r\nNumber.MIN_SAFE_INTEGER; \/\/ INT_MIN bei c\r\n\r\nNumber.isNan(x);\r\nNumber.isFinite(x);\r\nNumber.isInteger(x);\r\nNumber.isSafeInteger(x);\r\nNumber.parseFloat(x);\r\nNumber.parseInt(x);\r\n\r\nlet a = { b: 2};\r\nObject.extend(a, {c: 5, d:1}, {c: 42}); \/\/ \u00e4quivalent $.extend()\r\n\/\/ ==&amp;gt; a = { b: 2, c: 42, d: 1}\r\n\r\n<\/pre>\n<h2>let<\/h2>\n<p>Bei ES5 waren nur Variablendeklarationen mit dem var-Statement m\u00f6glich und waren in der gesamten aktuellen Funktion sichtbar (function scope). Speziell bei <em>for<\/em>-Schleifen oder innerhalb von Bl\u00f6cken konnte dies zu Problemen f\u00fchren und machte die Programmierung un\u00fcbersichtlich. Ab ES6 sind mit dem <em>let<\/em>-Schl\u00fcsselwort ganz normale Blockvariablen (beispielsweise wie in C) m\u00f6glich.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ Klassisch\r\nfunction abc()\r\n{\r\n  var b = 25;\r\n  \/\/ Variable a gibt es auch nach der For-Schleife noch!\r\n  for(var a=0; a&amp;lt;10; a++) \r\n  {\r\n    \/\/ Tempor\u00e4re Variable anlegen.\r\n    \/\/ \u00dcberschreibt leider den Wert von Variable b von oben.\r\n    var b = a*a; \r\n    console.log(b);\r\n  }\r\n\r\n  console.log(b); \/\/ Hier wird 81 ausgegeben.\r\n}\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nfunction abc()\r\n{\r\n  var b = 25;\r\n  \/\/ Variable a gibt nur innerhalb der For-Schleife.\r\n  for(let a=0; a&amp;lt;10; a++) \r\n  {\r\n    \/\/ Tempor\u00e4re Variable anlegen.\r\n    \/\/ Diese existiert nur in diesem Block und hat \r\n    \/\/ nichts mit b von oben zu tun.\r\n    let b = a*a; \r\n    console.log(b);\r\n  }\r\n\r\n  console.log(b); \/\/ Hier wird 25 ausgegeben.\r\n}\r\n<\/pre>\n<h2>const \/ freeze \/ seal<\/h2>\n<p>Bis dato fehlte ein <em>const<\/em>-Ausdruck f\u00fcr Variablen in JavaScript. Dies wurde nun zusammen mit <em>freeze<\/em> und <em>seal<\/em> erg\u00e4nzt.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\n\r\n\/\/ Konstantes Objekt erzeugen.\r\nconst a = { b: 25 };\r\na = 42; \/\/ Erzeugt einen TypeError\r\n\r\n\/\/ Die Werte eines konstanten Objekts k\u00f6nnen sich \r\n\/\/ jedoch noch \u00e4ndern.\r\na.b = 42; \/\/ funktioniert\r\n\r\n\/\/ Gegen weitere \u00c4nderung kann man das Objekt einfrieren\r\nObject.freeze(a);\r\n\r\n\/\/ Nun sind weder \u00c4nderungen an Struktur noch an den\r\n\/\/ Werten m\u00f6glich\r\na.b = 43; \/\/ TypeError\r\na.newParam = 10; \/\/ TypeError\r\n\r\n\/\/ M\u00f6chte man nur die Struktur verriegeln, Werte\u00e4nderungen\r\n\/\/ aber weiter zulassen, so gibt es die seal-Methode.\r\nvar b = {x: 5};\r\nObject.seal(b);\r\n<\/pre>\n<h2>Array-Funktionen<\/h2>\n<p>Die Methode <em>Array.from(x) <\/em> kann aus so ziemlich allem, was indizes und eine L\u00e4ngenangabe hat, ein Array erzeugen.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nArray.from(&quot;abc&quot;); \/\/ ==&amp;gt; Array&#x5B;&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]\r\n\r\nlet arrayObject = {\r\n  0: 'null',\r\n  1: 'eins',\r\n  2: 'zwei',\r\n  'length': 3\r\n};\r\n\r\nArray.from(arrayObject);\r\n\/\/ Array &#x5B;&quot;null&quot;, &quot;eins&quot;, &quot;zwei&quot;]\r\n<\/pre>\n<p>Zudem hat das Array-Objekt ein paar neue Methoden bekommen.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n&#x5B;'k','l','m'].keys()\r\n\/\/ ==&amp;gt; Array Iterator {}\r\n\r\n&#x5B;...&#x5B;'k','l','m'].keys()]\r\n\/\/ ==&amp;gt; Array &#x5B;0, 1, 2]\r\n\r\nArray.from(&#x5B;'k','l','m'].entries())\r\n\/\/ ==&amp;gt; &#x5B;&#x5B;0, &quot;k&quot;], &#x5B;1, &quot;l&quot;], &#x5B;2, &quot;m&quot;]]\r\n\r\nArray.from(&quot;abc&quot;); \/\/ ==&amp;gt; Array&#x5B;&quot;a&quot;,&quot;b&quot;,&quot;c&quot;]\r\n\r\nlet arrayObject = {\r\n  0: 'null',\r\n  1: 'eins',\r\n  2: 'zwei',\r\n  'length': 3\r\n};\r\n\r\nArray.from(arrayObject);\r\n\/\/ Array &#x5B;&quot;null&quot;, &quot;eins&quot;, &quot;zwei&quot;]\r\n\r\n&#x5B;1, 5, 50 ,15].find(x =&amp;gt; x&amp;gt;25);\r\n\/\/ 50\r\n\r\n&#x5B;1, 5, 50 ,15].findIndex(x =&amp;gt; x&amp;gt;25);\r\n\/\/ 2\r\n<\/pre>\n<h2>Arrow-Funktionen<\/h2>\n<p>Man kann sich bei Funktionen einen haufen Schreibarbeit sparen, speziell bei Callbacks.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES5\r\nvar f = function(x){\r\n  return x+1;\r\n}\r\n\r\n\/\/ ES6\r\nlet f = x =&amp;gt; x + 1;\r\n\r\n\/\/ Mit 2 Parametern:\r\nlet g = (x, y) =&amp;gt; x + y;\r\n\r\n\/\/ Ohne Parameter\r\nlet g = () =&amp;gt; 42;\r\n<\/pre>\n<p>Arrow-Funktionen haben einen weiteren Vorteil. Sie verwenden den this-Kontext von der \u00fcbergeordneten Funktion. Konstrukte wie .bind(this), that oder self entfallen damit!<\/p>\n<h2>Methoden in Objekten<\/h2>\n<p>Bei Methoden innerhalb von Objekten kann nun das Schl\u00fcsselwort <em>function<\/em> weggelassen werden.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ Klassisch\r\nvar object1 = {\r\n  a: function(x){\r\n    return x+25;\r\n  }\r\n};\r\n\r\n\/\/ ES6\r\nlet object1 = {\r\n  a(x) {\r\n    return x+25;\r\n  }\r\n};\r\n<\/pre>\n<h2>super<\/h2>\n<p>Von abgeleiteten Klassen (entweder TypeScript oder per abc.prototype) kann nun die \u00fcbergeordnete Methode aufgerufen werden.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nlet object3 = {\r\n  toString() {\r\n    return &quot;Ich bin ein &quot; + super.toString();\r\n  }\r\n};\r\n\r\nconsole.log(object3.toString()); \r\n\/\/ ==&amp;gt; Ich bin ein &#x5B;object Object]\r\n<\/pre>\n<h2>Berechnete properties<\/h2>\n<p>ES6 unterst\u00fctzt zum ersten Mal <em>computed properties<\/em>. Damit lassen sich \u00e4hnliche Felder oder Methoden definieren.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nlet object4 = {\r\n  &#x5B;'field' + ind]: 'this is field'+ind;\r\n\r\n  \/\/ Logarithmus von 'value' zur Basis 'base'\r\n  &#x5B;'log' +  base](value) {\r\n    return Math.log(value) \/ Math.log(base);\r\n  }\r\n};\r\n\r\nconsole.log(object4.field100); \/\/ ==&amp;gt; this is field 100\r\nconsole.log(object4.log2(8)); \/\/ ==&amp;gt; 3 (Logarithmus zur Basis 2 von 8)\r\n<\/pre>\n<h2>Klassen und Vererbung<\/h2>\n<p>ES6 unterst\u00fctzt Klassen und deren Vererbung. Das ganze sieht ziemlich \u00e4hnlich zu PHP aus.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nclass Jedi{\r\n  constructor()= {\r\n    this.forceIsDark = false;\r\n  }\r\n  toString() {\r\n    return (this.forceIsDark ? 'Join' : 'Fear is the path to')+\r\n      ' the dark side';\r\n  }\r\n};\r\n\r\nclass Sith extends Jedi {\r\n  constructor() {\r\n    super();\r\n    this.forceIsDark = true;\r\n  }\r\n}\r\n\r\nlet yoda = new Jedi();\r\nlet maul = new Sith();\r\n\r\nconsole.log(maul instanceof Sith); \/\/ ==&amp;gt; true\r\nconsole.log(maul instanceof Jedi); \/\/ ==&amp;gt; true\r\n\r\nconsole.log(yoda.toString()); \r\n\/\/ ==&amp;gt; Fear is the path to the dark side\r\n\r\nconsole.log(maul.toString()); \r\n\/\/ ==&amp;gt; Join the dark side\r\n<\/pre>\n<p>Au\u00dferdem unterst\u00fctzt ES6 statische Felder in Klassen.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nclass Foo{\r\n  static f(x){\r\n    return x+42;\r\n  }\r\n}\r\n\r\nconsole.log(Foo.f());\r\n<\/pre>\n<p>Eine Sache gibt es bei Klassen jedoch zu beachten: Im Gegensatz zu Funktionen sind Klassen erst ab der Zeile verf\u00fcgbar, wo sie deklariert wurden. Sie werden also nicht wie Funktionen nach oben gezogen (hoisting).<\/p>\n<h2>Getter\/Setter in Klassen<\/h2>\n<p>Man kennts schon von c#, nun geht das ganze auch in ES6.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nclass Foo{\r\n  constructor(){\r\n    this.r = 40\r\n  }\r\n\r\n  get radius() { return this.r; }\r\n  get durchmesser() { return this.r*2; }\r\n\r\n  set radius(val){\r\n    this.r = val;\r\n  }\r\n}\r\n\r\nconsole.log(Foo.f());\r\n<\/pre>\n<h2>Iteratoren<\/h2>\n<p>\u00dcber ein Array oder Objekt zu iterieren war bei ES5 ein ziemlicher Krampf. ES6 bietet nun endlich entsprechende Mechaniken.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES5\r\nvar arr = &#x5B;'1','2','3'];\r\nfor(var i in arr)\r\n  if(arr.hasOwnProperty(i))\r\n    console.log(i);\r\n\r\n\/\/ ES6\r\nfor(let i of &#x5B;'1','2','3'])\r\n  console.log(i);\r\n<\/pre>\n<p>In diesem Zusammenhang gibt es noch ein paar weitere <em>merkw\u00fcrdige Iteratoren<\/em>.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ Spread operator\r\n&#x5B;...&quot;abcd&quot;]; \/\/ ==&amp;gt; Array&#x5B;&quot;a&quot;,&quot;b&quot;,&quot;c&quot;,&quot;d&quot;]\r\n\r\n\/\/ Destructure assignment\r\n&#x5B;a,b] = &quot;xy&quot;; \/\/ ==&amp;gt; a=&quot;x&quot; , b=&quot;y&quot;\r\n<\/pre>\n<h2>Maps<\/h2>\n<p>Dies ist das \u00c4quivalent zu HashMap Strukturen in C#. W\u00e4hrend ES5 das ganze mit Objekten emuliert hat, geht es bei ES6 nun nativ.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar m = new Map(&#x5B;\r\n  &#x5B;1, 'erster'],\r\n  &#x5B;{}, 'zweiter']\r\n]);\r\n\r\nm.set(&quot;AA&quot;, &quot;dritter&quot;);\r\n\r\nm.delete(1);\r\n\r\nconsole.log(m.size); \/\/ ==&amp;gt; 2\r\n\r\nm.forEach((val, key) ==&amp;gt; console.log(val));\r\n\r\nm.clear();\r\n<\/pre>\n<p>Gleicheit bei den Schl\u00fcsseln (die \u00fcbrigens sogar Funktionen sein k\u00f6nnen) wird mit dem === Operator gepr\u00fcft. Daher ist {} !== {} !!!!<\/p>\n<h2>Sets<\/h2>\n<p>Im Prinzip wie Maps, jedoch nur mit value und ohne Key.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar s = new Set(&#x5B;&quot;blau&quot;, &quot;gelb&quot;]);\r\ns.add(&quot;lila&quot;);\r\n\r\ns.has(&quot;blau&quot;); \/\/ ==&amp;gt; true\r\n\r\n&#x5B;...s]; \r\n\/\/ ==&amp;gt; Array &#x5B;&quot;blau&quot;, &quot;gelb&quot;, &quot;lila&quot; ]\r\n<\/pre>\n<h2>Generatoren<\/h2>\n<p>Man kann nun Generatorfunktionen erzeugen. Mittels yield kehrt man zur\u00fcck zum Aufrufenden, der interne Zustand wird aber beibehalten und beim n\u00e4chsten Aufruf macht man nach dem yield weiter.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nfunction *genFour() {\r\n  yield 1;\r\n  yield 2;\r\n  yield 3;\r\n  return 4;\r\n}\r\n\r\n\/\/ Verwendung als Iterator\r\nlet four = genFour();\r\n\r\nfour.next(); \/\/ ==&amp;gt; { value: 1, done: false}\r\nfour.next(); \/\/ ==&amp;gt; { value: 2, done: false}\r\nfour.next(); \/\/ ==&amp;gt; { value: 3, done: false}\r\nfour.next(); \/\/ ==&amp;gt; { value: 4, done: true}\r\nfour.next(); \/\/ ==&amp;gt; { value: undefined , done: true}\r\n\r\n\/\/ Verwendung als Iterable\r\n&#x5B;...genFour()];\r\n\/\/ ==&amp;gt; Array &#x5B;1, 2, 3, 4]\r\n<\/pre>\n<h2>Promises<\/h2>\n<p>Um dem <em>Callback-Hell<\/em> zu entgehen, haben jQuery und andere Bibliotheken vor einigen Jahren Promises eingef\u00fchrt. Diese sind jetzt auch nativ in der Sprache verf\u00fcgbar.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nrequestFile()\r\n.then(function(result){ return readFile(result); }\r\n.then(function(result2){ .... return anotherresult; }\r\n.catch(function(error){ ...do something....; }\r\n<\/pre>\n<p>Sofern eine Funktion ein <em>thenable-Object<\/em> zur\u00fcckliefert, wird der nachfolgende then-Block erst aufgerufen, wenn ein Ergebnis aus dem <em>thenable-Object<\/em> vorliegt. Oben im Beispiel sieht man das an dem readFile-Aufruf. Ein Promise rezeugt man relativv einfach:<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nnew Promise(function(resolve, reject) {\r\n  if(checkSomething()){\r\n    resolve(cargoValue);\r\n  } else {\r\n    reject(cargoValue);\r\n  }\r\n});\r\n<\/pre>\n<p>Dabei kann ein Promise 3 Zust\u00e4nde annehmen: Pending, Resolved(fulfilled) oder Rejected.<\/p>\n<p>BTW: Wenn man einen ganzen Haufen von Promises hat, die erf\u00fcllt werden m\u00fcssen, bevor es weitergehen kann, sollte man die Methode Promise.all([]) verwenden, die ein Array von Promises annimmt und erst den then-Teil ausf\u00fchrt, wenn alle Promises den Status Pending verlassen haben.<\/p>\n<h2>Destructuring<\/h2>\n<p>&#8230;oder wie nehme ich Strukturen und Objekte wieder auseinander&#8230;?<\/p>\n<p>Man stelle sich vor, man hat eine Struktur (Objekt) und m\u00f6chte daraus ein paar Werte extrahieren.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nvar a = {x:1, y:2, z:3};\r\n\r\n\/\/ ES5\r\nvar x = a.x;  \/\/ Gleicher Name\r\nvar n = a.z;  \/\/ Unterschiedlicher Name\r\nconsole.log(x); \/\/ ==&amp;gt; 1\r\nconsole.log(n); \/\/ ==&amp;gt; 3\r\n\r\n\/\/ ES6\r\nlet {x:x, z:n} = a; \/\/ x -&amp;gt; x, z -&amp;gt; n\r\nconsole.log(x); \/\/ ==&amp;gt; 1\r\nconsole.log(n); \/\/ ==&amp;gt; 3\r\n<\/pre>\n<p>Bisher recht unspektakul\u00e4r. Interessant wird das ganze aber, wenn einzelne properties nicht im Objekt vorkommen. Dann kann man n\u00e4mlich Default-Werte definieren.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES6\r\nlet a = {x:1, y:2};\r\n\r\nlet {x:x = 40, z:n = 42 } = a; \/\/ x -&amp;gt; x, z -&amp;gt; n\r\nconsole.log(x); \/\/ ==&amp;gt; 1\r\nconsole.log(n); \/\/ ==&amp;gt; 42\r\n<\/pre>\n<p>Die Default-Werte werden <em>lazy<\/em> ausgewertet, das hei\u00dft, ihr Wert wird erst bestimmt, wenn er wirklich ben\u00f6tigt wird. Da man bei den Default-Werten auch Funktionen angeben kann, wird die Funktion erst aufgerufen, wenn der Default-Wert ben\u00f6tigt wird.<\/p>\n<p>Es gibt beim Destructuring noch einen Haufen weitere M\u00f6glichkeiten, beispielsweise mit Arrays oder der Extraktion verbleibender Werte, das w\u00fcrde aber an dieser Stelle den Rahmen sprengen. Au\u00dferdem hat <a href=\"https:\/\/developer.mozilla.org\/de\/docs\/Web\/JavaScript\/Reference\/Operators\/Destrukturierende_Zuweisung\">https:\/\/developer.mozilla.org\/de\/docs\/Web\/JavaScript\/Reference\/Operators\/Destrukturierende_Zuweisung<\/a> eine sehr gute \u00dcbersicht \u00fcber die M\u00f6glichkeiten.<\/p>\n<h1>ES7<\/h1>\n<h2>Neue Methoden<\/h2>\n<p>Diversen Standardobjekten wurden neue Methoden verpasst.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ String\r\n&quot;5&quot;.padLeft(4); \/\/ ==&amp;gt; &quot;   5&quot;\r\n&quot;1&quot;.padRight(2); \/\/ ==&amp;gt; &quot;1 &quot;\r\n&quot;3&quot;.padLeft(2,&quot;0&quot;); \/\/ ==&amp;gt; &quot;03&quot;\r\n<\/pre>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\nlet numbers = &#x5B;2, 3, 5, 9, 10];\r\n\r\n\/\/ ES6\r\nif(numbers.indexOf(5) !== -1)\r\n  console.log(&quot;5 ist drin&quot;);\r\n\r\n\/\/ ES7\r\nif(numbers.includes(5))\r\n  console.log(&quot;5 ist drin&quot;);\r\n<\/pre>\n<p>In einer fr\u00fcheren Version dieser Seite stand oben numbers.contain(5), was nat\u00fcrlich falsch ist. Vielen Dank an L3P3 f\u00fcr die Fehlermeldung!<\/p>\n<h2>Exponent-Operator<\/h2>\n<p>Seit ES7 gibt es einen Exponential-Operator.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES7\r\nlet n = 2 ** 10; \/\/ ==&amp;gt; 1024\r\n<\/pre>\n<h1>ES8<\/h1>\n<h2>async und await<\/h2>\n<p>Nachdem C# diese beiden Schl\u00fcsselw\u00f6rter eingef\u00fchrt hat, war es nur eine Frage der Zeit, wann das ganze in andere Programmiersprachen r\u00fcberschwappt. Man kann nun Methoden oder Funktionen als async deklarieren. Diese Funktionen m\u00fcssen dann ein Promise zur\u00fcckgeben.<\/p>\n<p>Mit dem await-Schl\u00fcsselwort kann man nun darauf warten, dass das Promise fertig wird.<\/p>\n<pre class=\"brush: jscript; title: ; notranslate\" title=\"\">\r\n\/\/ ES7\r\nasync function getData() { ... }\r\n\r\n\r\n(async function() {\r\n  await loadData();\r\n  console.log(&quot;Data successfully loaded!&quot;);\r\n}());\r\n<\/pre>\n<h2>Sonstiges<\/h2>\n<p>ES8 hat auch noch ein Event-Modell mit Observern und Subscribern, die Infos dar\u00fcber (und \u00fcber sinnvolle Anwendungsf\u00e4lle) halten sich jedoch derzeit noch in Grenzen.<br \/>\nZudem wurden neue Primitiven eingef\u00fchrt und die M\u00f6glichkeit, eigene Einheiten (z.B. L\u00e4ngeneinheiten) zu definieren.<\/p>\n<p>Eine weitere M\u00f6glichkeit besteht in der Operatoren-\u00dcberladung. Speziell, wenn man mit Vektoren und Matritzen arbeitet, k\u00f6nnte man damit vermutlich ganz nette Dinge bauen.<\/p>\n<p>Bei ES8 muss man sich jedoch im Klaren dar\u00fcber sein, dass es sich um bisher experimentelle Features handelt. Eine abschlie\u00dfende \u00dcbersicht bietet <a href=\"https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/New_in_JavaScript\/ECMAScript_Next_support_in_Mozilla\">https:\/\/developer.mozilla.org\/en-US\/docs\/Web\/JavaScript\/New_in_JavaScript\/ECMAScript_Next_support_in_Mozilla<\/a>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>ES6(ECMAScript 2015), ES7(ECMAScript 2016) und ES8(ECMAScript 2017) bringen einen Haufen Vorteile gegen\u00fcber normalem Javascript. In diesem Artikel m\u00f6chte ich die praktischsten vorstellen. ES6 ES6 wurde im Jahre 2015 finalisiert und war das bedeutendste Upgrade der JavaScript Programmiersprache. Dabei wurden viele Konzepte aus anderen Programmiersprachen \u00fcbernommen und Funktionen aus externen Bibliotheken in den Sprachkern integriert. W\u00e4hrend&#8230;<br \/><a class=\"read-more-button\" href=\"https:\/\/carsten.familie-schumann.info\/blog\/es6-es7-es8-features\/\">Mehr Lesen<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":0,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-175","page","type-page","status-publish","hentry"],"_links":{"self":[{"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/pages\/175","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/comments?post=175"}],"version-history":[{"count":25,"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/pages\/175\/revisions"}],"predecessor-version":[{"id":267,"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/pages\/175\/revisions\/267"}],"wp:attachment":[{"href":"https:\/\/carsten.familie-schumann.info\/blog\/wp-json\/wp\/v2\/media?parent=175"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}