Post on 18-Jan-2017
LET ECMASCRIPT = 6LET ECMASCRIPT = 6Wiktor Toporek
O MNIEO MNIEBlog: Na co dzień PHP i JSInspirują mnie inne języki programowania i podejścia
http://wiktortoporek.name/blog
WSTĘPWSTĘP
ECMASCRIPT VS JSECMASCRIPT VS JSPodzbiór JSJS implementuje ES
ES5 / ES5.1ES5 / ES5.1Metody Object.*: .create(), .defineProperty(), ...Natywny support JSONaMetody w Arrayach: .forEach(),.map(), .filter(), ...
ES6ES6
Źródło: http://reddit.com/r/gifs
FICZERY ES6FICZERY ES6AGENDAAGENDA
1. Arrow functions2. let & const3. Template strings4. Destrukturyzacja5. class6. Promise7. Moduły
ARROW FUNCTIONSARROW FUNCTIONS() => {}() => {}
Źródło obrazka: http://www.bronzemoonoutdoors.com.au
/* examples/arrow/01-filter.js */
var numbers = [1, 2, 3, 4, 5, 6];var even = numbers.filter(function(x) { return x % 2 == 0;});
console.log(even); //[ 2, 4, 6 ]
/* examples/arrow/02-arrow-filter.js */
var numbers = [1, 2, 3, 4, 5, 6];var even = numbers.filter(x => x % 2 == 0);
console.log(even); //[ 2, 4, 6 ]
PROSTA SKŁADNIAPROSTA SKŁADNIAx => x * 2
function(x) {return x * 2;}
WIELE ARGUMENTÓWWIELE ARGUMENTÓW(x, y) => x + y
function(x, y) {return x + y;}
BRAK ARGUMENTÓWBRAK ARGUMENTÓW() => 2 + 2
function() {return 2 + 2;}
BARDZIEJ ZŁOŻONE CIAŁO FUNKCJIBARDZIEJ ZŁOŻONE CIAŁO FUNKCJI(x, y) => { console.log(x); return x+y;}
function(x, y) { console.log(x); return x+y;}
NIE TYLKONIE TYLKO"SYNTACTIC SUGAR""SYNTACTIC SUGAR"
Źródło obrazka: https://en.wikipedia.org/wiki/Sugar
/* examples/arrow/03-buggy-timer.js */
var Timer = function() { this.secs = 0;};Timer.prototype.start = function() { setInterval(function() { this.secs++; }, 1000);};
var timer = new Timer();timer.start();
/* examples/arrow/04-corrected-timer.js */
var Timer = function() { this.secs = 0;};Timer.prototype.start = function() { var that = this; setInterval(function() { that.secs++; }, 1000);};
var timer = new Timer();timer.start();
/* examples/arrow/05-arrow-func-timer.js */
var Timer = function() { this.secs = 0;};Timer.prototype.start = function() { setInterval(() => {this.secs++;}, 1000);};
var timer = new Timer();timer.start();
LETLET & & CONSTCONSTŹródło obrazka: https://www.flickr.com/photos/mtip/4562826679
/* examples/letnconst/01-tricky-async-var.js */
for (var i=1; i <= 10; ++i) { setTimeout(function() {console.log(i);}, i * 1000);}
/* examples/letnconst/02-tricky-async-var-corrected.js */
for (var i=1; i <= 10; ++i) { (function(i) { setTimeout(function() {console.log(i);}, i * 1000); })(i);}
/* examples/letnconst/03-let.js */
"use strict";
for (let i=1; i <= 10; ++i) { setTimeout(function() {console.log(i);}, i * 1000);}
/* examples/letnconst/04-let-in-if.js */
"use strict";
if (true) { let foo = 'bar';}console.log(foo); // ReferenceError: foo is not defined
var - function scopelet - block (if, for, etc) scope
/* examples/letnconst/05-tricky-var.js */
var x = 'foo';(function() { console.log(x); var x = 'bar';})();
/* examples/letnconst/06-tricky-var-explained.js */
var x = 'foo';(function() { var x; console.log(x); x = 'bar';})();
/* examples/letnconst/07-beware-tdz.js */
'use strict';
let foo = 'bar';if (true) { console.log(foo); /* ReferenceError (due to Temporal Dead Zone)*/ let foo = 'bar';}
CONSTCONST
/* examples/letnconst/08-const.js */
const x = 1;
x++;
console.log(x); //1
/* examples/letnconst/09-const-strict.js */
"use strict";
const x = 1;
x++; /*SyntaxError*/
console.log(x);
Źródło: http://reddit.com/r/gifs
/* examples/letnconst/10-const-object.js */
const obj = {x: 1, y: 2};console.log(obj); /*Object {x: 1, y: 2}*/
obj.x = 'foo!';console.log(obj); //Object {x: "foo!", y: 2} :-(
TEMPLATE STRINGSTEMPLATE STRINGSŹródło obrazka: https://www.flickr.com/photos/alexfiles/3106114417
/* examples/template-strings/01-classic-string-concat.js */
var firstName = 'John';var lastName = 'Doe';var fullName = firstName + ' ' + lastName;
console.log(fullName);
/* examples/template-strings/02-template-string.js */
var firstName = 'John';var lastName = 'Doe';var fullName = `${firstName} ${lastName}`;
console.log(fullName);
/* examples/template-strings/03-template-string-multiline.js */
var multilineText = `first linesecondthird`;
console.log(multilineText);/* Output: first line second third */
DESTRUKTURYZACJADESTRUKTURYZACJAŹródło obrazka: http://www.autoevolution.com/news/stunning-deconstruction-of-f1-car-at-
mercedes-benz-world-32294.html
/* examples/destruct/01-destruct.js */
/*Arrays*/var [el1, , el3] = [1, 2, 3];
console.log(el1, el3); /*1 3*/
/*Objects*/var john = { firstName: 'John', lastName: 'Doe'};
var {firstName, lastName} = john;console.log(firstName, lastName); /*John Doe*/
/* examples/destruct/02-spread.js */
var head, rest;[head, ...rest] = [1, 2, 3, 4, 5];
console.log(head); /*1*/console.log(rest); /*[2, 3, 4, 5]*/
var array1 = [1,2,3], array2 = [4,5,6];
/*ES5: array1.push.apply(array1, array2);*/array1.push(...array2);
console.log(array1); //[1,2,3,4,5,6]
/* examples/destruct/03-func-many-params.js */
function ajax(url, method, async, headers) { if (method === undefined) { method = 'get'; }
if (async === undefined) { async = true; }
if (headers === undefined) { headers = {}; }
console.log(method, url, async ? 'async' : 'sync');
console.log('headers:', headers);}
/* get http://google.com sync headers: {} */ajax('http://google.com', 'get', false);
/* examples/destruct/04-func-params-es6.js */
function ajax({url, method = 'get', async = true, headers = {}}) { console.log(method, url, async ? 'async' : 'sync'); console.log('headers:', headers);}
/*get http://google.com syncheaders: {} */ajax({url: 'http://google.com', async: false});
CLASSCLASSŹródło obrazka: http://cufflinkedmag.com/2014/07/14/keepin-it-classy-7-things-you-will-never-see-
in-cufflinked-magazine/
/* examples/class/01-es5.js */
function Person(firstName, lastName) { this.firstName = firstName; this.lastName = lastName;}Person.prototype.say = function(what) { console.log(this.firstName+' '+this.lastName+' says: '+what);};
var john = new Person('John', 'Doe');john.say('Hello!');
/* examples/class/02-es6.js */
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }
say(what) { console.log(`${this.firstName} ${this.lastName} says: ${what}`); }}
var john = new Person('John', 'Doe');john.say('Hello!');
/* examples/class/03-inheritance.js */
class Person { constructor(firstName, lastName) { this.firstName = firstName; this.lastName = lastName; }
getFullName() { return [this.firstName, this.lastName].join(' '); }
toString() { return 'Person ' + this.getFullName(); }
}
class Employee extends Person { constructor(firstName, lastName, jobTitle) { super(firstName, lastName); this.jobTitle = jobTitle; } toString() { return `${super.toString()} (${this.jobTitle})`; }}
var john = new Person('John', 'Doe');var wiktor = new Employee('Wiktor', 'Toporek', 'PHP Programmer');
console.log(john.toString()); /*Person: John Doe*/console.log(wiktor.toString()); //Person: Wiktor Toporek (PHP Programmer)
/* examples/class/04-dynamic-inheritance.js */
const CarMixin = { ride() { console.log('Riding...'); }};
const SailingMixin = { sail() { console.log('Sailing...') }};
function mixin(...mixins) { var base = function() {}; Object.assign(base.prototype, ...mixins); return base;}
class Amphibian extends mixin(CarMixin, SailingMixin) {}
var amphibian = new Amphibian();amphibian.ride(); /*Riding...*/amphibian.sail(); /*Sailing...*/
/* examples/class/05-gettersnsetters.js */
class Rectangle { constructor(width, height) { this.width = width; this.height = height; this._scale = 1; }
get area() { return this.width * this.height; }
set scale(newScale) { var prevScale = this._scale; this._scale = newScale; this.width *= newScale / prevScale; this.height *= newScale / prevScale; }
get scale() { return this._scale; }}
var rect = new Rectangle(10, 10);console.log(rect.area); /*100*/
rect.scale = 0.5;console.log(rect.area); /*25*/
rect.scale = 1;console.log(rect.area); //100
/* examples/class/06-static.js */
class Point { constructor(x, y) { this.x = x; this.y = y; }
static distance(a, b) { const dx = a.x - b.x; const dy = a.y - b.y;
return Math.sqrt(dx*dx + dy*dy); }}
const p1 = new Point(5, 5);const p2 = new Point(10, 10);
console.log(Point.distance(p1, p2));
/* examples/class/07-hoisting.js */
var foo = new Bar(); /* ReferenceError*/
class Bar {}
ZALETYZALETYŁatwa przejrzysta składniaSkładnia bliższa dla programistów z innych języków OO(np. Java)Łatwiejsze dziedziczenie z extends
WADYWADYMamy kilka sposobów tworzenia obiektów. Po co kolejny?Brakuje Access modifierów dla metod np. privateBrak wsparcia dla deklarowania właściwości klasy
PROMISEPROMISEŹródło obrazka: http://thenextweb.com/lifehacks/2014/03/30/always-promise-deliver/
/* examples/promise/01-promise.js */
function timeout(duration = 0) { return new Promise((resolve, reject) => { setTimeout(resolve, duration); })}
var p = timeout(1000).then(() => { return timeout(2000);}).then(() => { throw new Error("hmm");}).catch(err => { return Promise.all([timeout(100), timeout(200)]);})
MODUŁYMODUŁYŹródło obrazka: http://www.officescope.com/blog/wp-content/uploads/2013/07/Puzzle-pieces.jpg
POZOSTAŁE FICZERYPOZOSTAŁE FICZERYGeneratoryfor..ofSymbolUnicodeSubclassable Built-ins (m.in. elementy DOM)Array.from / Array.ofProxyOptymalizacja "Tail Call"i inne...
Źródło: http://reddit.com/r/gifs
JAK UŻYWAĆ?JAK UŻYWAĆ?
COMPATIBILITY TABLECOMPATIBILITY TABLE
BACKENDBACKENDnode --harmony - tylko 17% ficzerówio.js - 44% ficzerów
Czekamy na implementacje i olewamy stare przeglądarki?
FRONTENDFRONTEND
BEZPIECZNA DROGA:BEZPIECZNA DROGA:TRANSPILACJATRANSPILACJA
npm install --global babel
babel es6-script.js --out-file es5-script-file.js
NA CO ZWRÓCIĆ UWAGĘ?NA CO ZWRÓCIĆ UWAGĘ?Część ficzerów wymaga babel/polyfillProxy nie możliwe do przetłumaczenia na ES5
Źródło obrazka: http://www.successfulworkplace.org/wp-content/uploads/2013/05/the-future.jpg
Źródło obrazka: http://www.successfulworkplace.org/wp-content/uploads/2013/05/the-future.jpg
ES7?ES7?operator **async functionsObject.observeoperator ::SIMDTrailing commas in function syntax:function(a,b,c,){}
>=ES8?>=ES8?Makra?
THANKYOU.JSTHANKYOU.JSPYTANIA.JS ?PYTANIA.JS ?