LET ECMASCRIPT = 6LET ECMASCRIPT = 6
Wiktor Toporek
O MNIEO MNIE
Blog:
Na co dzień PHP i JS
Inspirują mnie inne języki programowania i podejścia
http://wiktortoporek.name/blog
WSTĘPWSTĘP
ECMASCRIPT VS JSECMASCRIPT VS JS
Podzbiór JS
JS implementuje ES
ES5 / ES5.1ES5 / ES5.1
Metody Object.*:
.create(),
.defineProperty(), ...
Natywny support JSONa
Metody w Arrayach:
.forEach(),
.map(),
.filter(), ...
ES6ES6
Źródło: http://reddit.com/r/gifs
FICZERY ES6FICZERY ES6
AGENDAAGENDA
1. Arrow functions
2. let & const
3. Template strings
4. Destrukturyzacja
5. class
6. Promise
7. 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ŁADNIA
x => 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 scope
let - 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 line
second
third
`;
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 sync
headers: {}
*/
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ładnia
Składnia bliższa dla programistów z innych języków OO
(np. Java)
Łatwiejsze dziedziczenie z extends
WADYWADY
Mamy kilka sposobów tworzenia obiektów. Po co kolejny?
Brakuje Access modifierów dla metod np. private
Brak 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 FICZERY
Generatory
for..of
Symbol
Unicode
Subclassable Built-ins (m.in. elementy DOM)
Array.from / Array.of
Proxy
Optymalizacja "Tail Call"
i inne...
Źródło: http://reddit.com/r/gifs
JAK UŻYWAĆ?JAK UŻYWAĆ?
COMPATIBILITY TABLECOMPATIBILITY TABLE
BACKENDBACKEND
node --harmony - tylko 17% ficzerów
io.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/polyfill
Proxy 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 functions
Object.observe
operator ::
SIMD
Trailing commas in function syntax:
function(a,b,c,){}
>=ES8?>=ES8?
Makra?
THANKYOU.JSTHANKYOU.JS
PYTANIA.JS ?PYTANIA.JS ?

"let ECMAScript = 6"